diff --git a/boards/arm/nucleo_h723zg/arduino_r3_connector.dtsi b/boards/arm/nucleo_h723zg/arduino_r3_connector.dtsi index 172fadfabee8c..6d5288633d2e7 100644 --- a/boards/arm/nucleo_h723zg/arduino_r3_connector.dtsi +++ b/boards/arm/nucleo_h723zg/arduino_r3_connector.dtsi @@ -35,5 +35,5 @@ }; arduino_i2c: &i2c1 {}; - +arduino_spi: &spi1 {}; arduino_serial: &uart8 {}; diff --git a/boards/arm/nucleo_h723zg/doc/index.rst b/boards/arm/nucleo_h723zg/doc/index.rst index 3df5540abffc0..4bf531006b8e0 100644 --- a/boards/arm/nucleo_h723zg/doc/index.rst +++ b/boards/arm/nucleo_h723zg/doc/index.rst @@ -107,6 +107,8 @@ features: +-------------+------------+-------------------------------------+ | I2C | on-chip | i2c | +-------------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-------------+------------+-------------------------------------+ | PWM | on-chip | pwm | +-------------+------------+-------------------------------------+ | ETHERNET | on-chip | ethernet | @@ -135,6 +137,7 @@ and a ST morpho connector. Board is configured as follows: - LD2 : PB7 - LD3 : PB14 - I2C : PB8, PB9 +- SPI1 NSS/SCK/MISO/MOSI : PD14PA5/PA6/PB5 (Arduino SPI) System Clock ------------ diff --git a/boards/arm/nucleo_h723zg/nucleo_h723zg.dts b/boards/arm/nucleo_h723zg/nucleo_h723zg.dts index 02e1ed590f221..171b825f9432d 100644 --- a/boards/arm/nucleo_h723zg/nucleo_h723zg.dts +++ b/boards/arm/nucleo_h723zg/nucleo_h723zg.dts @@ -115,6 +115,13 @@ status = "okay"; }; +&spi1 { + status = "okay"; + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pb5>; + pinctrl-names = "default"; + cs-gpios = <&gpiod 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; +}; + &i2c1 { pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; pinctrl-names = "default"; diff --git a/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml b/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml index 0539a8926fb68..98a6a0efcf592 100644 --- a/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml +++ b/boards/arm/nucleo_h723zg/nucleo_h723zg.yaml @@ -11,10 +11,12 @@ flash: 1024 supported: - arduino_gpio - arduino_i2c + - arduino_spi - uart - gpio - counter - i2c - pwm + - spi - netif:eth - backup_sram diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 058c5a0cc94d2..56f0eaf69579a 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RCAR_CPG_MSSR clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RV32M1_PCC clock_control_rv32m1_pcc.c) if(CONFIG_CLOCK_CONTROL_STM32_CUBE) + zephyr_library_sources_ifdef(CONFIG_CLOCK_STM32_MUX clock_stm32_mux.c) if(CONFIG_SOC_SERIES_STM32MP1X) zephyr_library_sources(clock_stm32_ll_mp1.c) elseif(CONFIG_SOC_SERIES_STM32H7X) diff --git a/drivers/clock_control/Kconfig.stm32 b/drivers/clock_control/Kconfig.stm32 index 83b70832bcba3..ba4d441656462 100644 --- a/drivers/clock_control/Kconfig.stm32 +++ b/drivers/clock_control/Kconfig.stm32 @@ -8,7 +8,7 @@ menuconfig CLOCK_CONTROL_STM32_CUBE bool "STM32 Reset & Clock Control" depends on SOC_FAMILY_STM32 select USE_STM32_LL_UTILS - select USE_STM32_LL_RCC if SOC_SERIES_STM32MP1X + select USE_STM32_LL_RCC if (SOC_SERIES_STM32MP1X || SOC_SERIES_STM32H7X) help Enable driver for Reset & Clock Control subsystem found in STM32 family of MCUs @@ -17,6 +17,7 @@ if CLOCK_CONTROL_STM32_CUBE DT_STM32_HSE_CLOCK := $(dt_nodelabel_path,clk_hse) DT_STM32_HSE_CLOCK_FREQ := $(dt_node_int_prop_int,$(DT_STM32_HSE_CLOCK),clock-frequency) +DT_COMPAT_ST_MUX_CLOCK := st,stm32-clock-mux config CLOCK_STM32_HSE_CLOCK int "HSE clock value" @@ -33,6 +34,15 @@ config CLOCK_STM32_HSE_CLOCK Note: Device tree configuration is overridden when current symbol is set: CONFIG_CLOCK_STM32_HSE_CLOCK=32000000 +config CLOCK_STM32_MUX + bool "STM32 clock mux driver" + default $(dt_compat_enabled,$(DT_COMPAT_ST_MUX_CLOCK)) + help + Enable driver for STM32 clock mux which don't match an + existing clock hardware block but allows to select a clock + for a specific domain. For instance per_ck clock on STM32H7 or + CLK48 clock + # Micro-controller Clock output configuration options choice diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index 846972374dcd4..726e13d9ee3a2 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -16,6 +16,7 @@ #include #include #include "clock_stm32_ll_common.h" +#include "stm32_hsem.h" /* Macros to fill up prescaler values */ #define fn_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v @@ -35,16 +36,6 @@ #define fn_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v #define mco2_prescaler(v) fn_mco2_prescaler(v) -/* Calculate MSI freq for the given range (at RUN range, not after standby) */ -#if !defined(LL_RCC_MSIRANGESEL_RUN) -/* CONFIG_SOC_SERIES_STM32WBX or CONFIG_SOC_SERIES_STM32L0X or CONFIG_SOC_SERIES_STM32L1X */ -#define RCC_CALC_MSI_RUN_FREQ() __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()) -#else -/* mainly CONFIG_SOC_SERIES_STM32WLX or CONFIG_SOC_SERIES_STM32L4X or CONFIG_SOC_SERIES_STM32L5X */ -#define RCC_CALC_MSI_RUN_FREQ() __LL_RCC_CALC_MSI_FREQ( \ - LL_RCC_MSIRANGESEL_RUN, LL_RCC_MSI_GetRange()) -#endif - #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler) #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK4_FREQ #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB4Prescaler @@ -56,16 +47,89 @@ #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHBPrescaler #endif -/* Identify stm32wl dual-core socs by symbol defined in CMSIS dev header file */ -#if (defined(CONFIG_SOC_SERIES_STM32WLX) && defined(DUAL_CORE)) -#define STM32WL_DUAL_CORE -#endif - static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler) { return clock / prescaler; } +__unused +static uint32_t get_msi_frequency(void) +{ +#if defined(STM32_MSI_ENABLED) +#if !defined(LL_RCC_MSIRANGESEL_RUN) + return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()); +#else + return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, + LL_RCC_MSI_GetRange()); +#endif +#endif + return 0; +} + +/** @brief Verifies clock is part of active clock configuration */ +__unused +static int enabled_clock(uint32_t src_clk) +{ + int r = 0; + + switch (src_clk) { +#if defined(STM32_SRC_SYSCLK) + case STM32_SRC_SYSCLK: + break; +#endif /* STM32_SRC_SYSCLK */ +#if defined(STM32_SRC_PCLK) + case STM32_SRC_PCLK: + break; +#endif /* STM32_SRC_PCLK */ +#if defined(STM32_SRC_HSE) + case STM32_SRC_HSE: + if (!IS_ENABLED(STM32_HSE_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_HSE */ +#if defined(STM32_SRC_HSI) + case STM32_SRC_HSI: + if (!IS_ENABLED(STM32_HSI_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_HSI */ +#if defined(STM32_SRC_LSE) + case STM32_SRC_LSE: + if (!IS_ENABLED(STM32_LSE_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_LSE */ +#if defined(STM32_SRC_LSI) + case STM32_SRC_LSI: + if (!IS_ENABLED(STM32_LSI_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_LSI */ +#if defined(STM32_SRC_MSI) + case STM32_SRC_MSI: + if (!IS_ENABLED(STM32_MSI_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_MSI */ +#if defined(STM32_SRC_PLLCLK) + case STM32_SRC_PLLCLK: + if (!IS_ENABLED(STM32_PLL_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_PLLCLK */ + default: + return -ENOTSUP; + } + + return r; +} + static inline int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) { @@ -83,7 +147,6 @@ static inline int stm32_clock_control_on(const struct device *dev, return 0; } - static inline int stm32_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system) { @@ -106,6 +169,40 @@ static inline int stm32_clock_control_off(const struct device *dev, return 0; } +static inline int stm32_clock_control_configure(const struct device *dev, + clock_control_subsys_t sub_system, + void *data) +{ +#if defined(STM32_SRC_CLOCK_MIN) + /* At least one alt src clock available */ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + volatile uint32_t *reg; + uint32_t reg_val, dt_val; + int err; + + ARG_UNUSED(dev); + ARG_UNUSED(data); + + err = enabled_clock(pclken->bus); + if (err < 0) { + /* Attempt to configure a src clock not available or not valid */ + return err; + } + + dt_val = STM32_CLOCK_VAL_GET(pclken->enr) << + STM32_CLOCK_SHIFT_GET(pclken->enr); + reg = (uint32_t *)(DT_REG_ADDR(DT_NODELABEL(rcc)) + + STM32_CLOCK_REG_GET(pclken->enr)); + reg_val = *reg; + reg_val |= dt_val; + *reg = reg_val; + + return 0; +#else + /* No src clock available: Not supported */ + return -ENOTSUP; +#endif +} static int stm32_clock_control_get_subsys_rate(const struct device *clock, clock_control_subsys_t sub_system, @@ -134,6 +231,14 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, uint32_t ahb3_clock = ahb_clock; #endif +#if defined(STM32_SRC_PCLK) + if (pclken->bus == STM32_SRC_PCLK) { + /* STM32_SRC_PCLK can't be used to request a subsys freq */ + /* Use STM32_CLOCK_BUS_FOO instead. */ + return -ENOTSUP; + } +#endif + ARG_UNUSED(clock); switch (pclken->bus) { @@ -167,6 +272,39 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, /* STM32WL: AHB3 and APB3 share the same clock and prescaler. */ *rate = ahb3_clock; break; +#endif +#if defined(STM32_SRC_SYSCLK) + case STM32_SRC_SYSCLK: + *rate = SystemCoreClock * STM32_CORE_PRESCALER; + break; +#endif +#if defined(STM32_SRC_PLLCLK) & defined(STM32_SYSCLK_SRC_PLL) + case STM32_SRC_PLLCLK: + if (get_pllout_frequency() == 0) { + return -EIO; + } + *rate = get_pllout_frequency(); + break; +#endif +#if defined(STM32_SRC_LSE) + case STM32_SRC_LSE: + *rate = STM32_LSE_FREQ; + break; +#endif +#if defined(STM32_SRC_LSI) + case STM32_SRC_LSI: + *rate = STM32_LSI_FREQ; + break; +#endif +#if defined(STM32_SRC_HSI) + case STM32_SRC_HSI: + *rate = STM32_HSI_FREQ; + break; +#endif +#if defined(STM32_SRC_HSE) + case STM32_SRC_HSE: + *rate = STM32_HSE_FREQ; + break; #endif default: return -ENOTSUP; @@ -179,6 +317,7 @@ static struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, + .configure = stm32_clock_control_configure, }; /* @@ -220,10 +359,9 @@ static inline void stm32_clock_control_mco_init(void) } __unused -static int set_up_plls(void) +static void set_up_plls(void) { #if defined(STM32_PLL_ENABLED) - int r; /* * Case of chain-loaded applications: @@ -259,10 +397,7 @@ static int set_up_plls(void) << RCC_PLLCFGR_PLLQ_Pos); #endif - r = config_pll_sysclock(); - if (r < 0) { - return -ENOTSUP; - } + config_pll_sysclock(); /* Enable PLL */ LL_RCC_PLL_Enable(); @@ -271,8 +406,6 @@ static int set_up_plls(void) } #endif /* STM32_PLL_ENABLED */ - - return 0; } static void set_up_fixed_clock_sources(void) @@ -342,6 +475,44 @@ static void set_up_fixed_clock_sources(void) } #endif /* STM32_MSI_ENABLED */ + if (IS_ENABLED(STM32_LSI_ENABLED)) { +#if defined(CONFIG_SOC_SERIES_STM32WBX) + LL_RCC_LSI1_Enable(); + while (LL_RCC_LSI1_IsReady() != 1) { + } +#else + LL_RCC_LSI_Enable(); + while (LL_RCC_LSI_IsReady() != 1) { + } +#endif + } + + if (IS_ENABLED(STM32_LSE_ENABLED)) { + /* LSE belongs to the back-up domain, enable access.*/ + + z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); + + /* Set the DBP bit in the Power control register 1 (PWR_CR1) */ + LL_PWR_EnableBkUpAccess(); + while (!LL_PWR_IsEnabledBkUpAccess()) { + /* Wait for Backup domain access */ + } + +#if STM32_LSE_DRIVING + /* Configure driving capability */ + LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos); +#endif + + /* Enable LSE Oscillator (32.768 kHz) */ + LL_RCC_LSE_Enable(); + while (!LL_RCC_LSE_IsReady()) { + /* Wait for LSE ready */ + } + + LL_PWR_DisableBkUpAccess(); + + z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); + } } /** @@ -358,8 +529,6 @@ static void set_up_fixed_clock_sources(void) */ int stm32_clock_control_init(const struct device *dev) { - int r; - ARG_UNUSED(dev); /* Some clocks would be activated by default */ @@ -385,10 +554,7 @@ int stm32_clock_control_init(const struct device *dev) set_up_fixed_clock_sources(); /* Set up PLLs */ - r = set_up_plls(); - if (r < 0) { - return r; - } + set_up_plls(); if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) && (STM32_CORE_PRESCALER == LL_RCC_SYSCLK_DIV_1) && diff --git a/drivers/clock_control/clock_stm32_ll_common.h b/drivers/clock_control/clock_stm32_ll_common.h index 7db724c7f748f..69280245c1fe9 100644 --- a/drivers/clock_control/clock_stm32_ll_common.h +++ b/drivers/clock_control/clock_stm32_ll_common.h @@ -33,7 +33,8 @@ #endif #ifdef STM32_SYSCLK_SRC_PLL -int config_pll_sysclock(void); +void config_pll_sysclock(void); +uint32_t get_pllout_frequency(void); #endif void config_enable_default_clocks(void); diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index ef3982f8a7899..1d27b287f4a90 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -17,6 +17,7 @@ #include #include "stm32_hsem.h" + /* Macros to fill up prescaler values */ #define z_hsi_divider(v) LL_RCC_HSI_DIV ## v #define hsi_divider(v) z_hsi_divider(v) @@ -168,9 +169,9 @@ static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler) __unused static uint32_t get_pllout_frequency(uint32_t pllsrc_freq, - int pllm_div, - int plln_mul, - int pllout_div) + int pllm_div, + int plln_mul, + int pllout_div) { __ASSERT_NO_MSG(pllm_div && pllout_div); @@ -321,6 +322,29 @@ static uint32_t get_vco_output_range(uint32_t vco_input_range) #endif /* ! CONFIG_CPU_CORTEX_M4 */ +/** @brief Verifies clock is part of actve clock configuration */ +static int enabled_clock(uint32_t src_clk) +{ + + if ((src_clk == STM32_SRC_SYSCLK) || + ((src_clk == STM32_SRC_CKPER) && IS_ENABLED(STM32_CKPER_ENABLED)) || + ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) || + ((src_clk == STM32_SRC_HSI_KER) && IS_ENABLED(STM32_HSI_ENABLED)) || + ((src_clk == STM32_SRC_CSI_KER) && IS_ENABLED(STM32_CSI_ENABLED)) || + ((src_clk == STM32_SRC_LSE) && IS_ENABLED(STM32_LSE_ENABLED)) || + ((src_clk == STM32_SRC_LSI) && IS_ENABLED(STM32_LSI_ENABLED)) || + ((src_clk == STM32_SRC_PLL1_P) && IS_ENABLED(STM32_PLL_P_ENABLED)) || + ((src_clk == STM32_SRC_PLL1_Q) && IS_ENABLED(STM32_PLL_Q_ENABLED)) || + ((src_clk == STM32_SRC_PLL1_R) && IS_ENABLED(STM32_PLL_R_ENABLED)) || + ((src_clk == STM32_SRC_PLL3_P) && IS_ENABLED(STM32_PLL3_P_ENABLED)) || + ((src_clk == STM32_SRC_PLL3_Q) && IS_ENABLED(STM32_PLL3_Q_ENABLED)) || + ((src_clk == STM32_SRC_PLL3_R) && IS_ENABLED(STM32_PLL3_R_ENABLED))) { + return 0; + } + + return -ENOTSUP; +} + static inline int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) { @@ -373,6 +397,40 @@ static inline int stm32_clock_control_off(const struct device *dev, return 0; } +static inline int stm32_clock_control_configure(const struct device *dev, + clock_control_subsys_t sub_system, + void *data) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + volatile uint32_t *reg; + uint32_t reg_val, dt_val; + int err; + + ARG_UNUSED(dev); + ARG_UNUSED(data); + + err = enabled_clock(pclken->bus); + if (err < 0) { + /* Attemp to configure a src clock not available or not valid */ + return err; + } + + z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); + + dt_val = STM32_CLOCK_VAL_GET(pclken->enr) << + STM32_CLOCK_SHIFT_GET(pclken->enr); + reg = (uint32_t *)(DT_REG_ADDR(DT_NODELABEL(rcc)) + + STM32_CLOCK_REG_GET(pclken->enr)); + reg_val = *reg; + reg_val &= ~dt_val; + reg_val |= dt_val; + *reg = reg_val; + + z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); + + return 0; +} + static int stm32_clock_control_get_subsys_rate(const struct device *clock, clock_control_subsys_t sub_system, uint32_t *rate) @@ -416,6 +474,69 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, case STM32_CLOCK_BUS_APB4: *rate = apb4_clock; break; + case STM32_SRC_SYSCLK: + *rate = get_hclk_frequency(); + break; +#if defined(STM32_CKPER_ENABLED) + case STM32_SRC_CKPER: + *rate = LL_RCC_GetCLKPClockFreq(LL_RCC_CLKP_CLKSOURCE); + break; +#endif /* STM32_CKPER_ENABLED */ +#if defined(STM32_HSE_ENABLED) + case STM32_SRC_HSE: + *rate = STM32_HSE_FREQ; + break; +#endif /* STM32_HSE_ENABLED */ +#if defined(STM32_LSE_ENABLED) + case STM32_SRC_LSE: + *rate = STM32_LSE_FREQ; + break; +#endif /* STM32_LSE_ENABLED */ +#if defined(STM32_LSI_ENABLED) + case STM32_SRC_LSI: + *rate = STM32_LSI_FREQ; + break; +#endif /* STM32_LSI_ENABLED */ +#if defined(STM32_PLL_ENABLED) + case STM32_SRC_PLL1_P: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_P_DIVISOR); + break; + case STM32_SRC_PLL1_Q: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_Q_DIVISOR); + break; + case STM32_SRC_PLL1_R: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_R_DIVISOR); + break; +#endif /* STM32_PLL_ENABLED */ +#if defined(STM32_PLL3_ENABLED) + case STM32_SRC_PLL3_P: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL3_M_DIVISOR, + STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_P_DIVISOR); + break; + case STM32_SRC_PLL3_Q: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL3_M_DIVISOR, + STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_Q_DIVISOR); + break; + case STM32_SRC_PLL3_R: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL3_M_DIVISOR, + STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_R_DIVISOR); + break; +#endif /* STM32_PLL3_ENABLED */ default: return -ENOTSUP; } @@ -427,6 +548,7 @@ static struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, + .configure = stm32_clock_control_configure, }; __unused diff --git a/drivers/clock_control/clock_stm32_ll_u5.c b/drivers/clock_control/clock_stm32_ll_u5.c index 267f636841b7b..72c8223f7d7ef 100644 --- a/drivers/clock_control/clock_stm32_ll_u5.c +++ b/drivers/clock_control/clock_stm32_ll_u5.c @@ -71,6 +71,57 @@ static uint32_t get_startup_frequency(void) } } +__unused +static uint32_t get_pllout_frequency(uint32_t pllsrc_freq, + int pllm_div, + int plln_mul, + int pllout_div) +{ + __ASSERT_NO_MSG(pllm_div && pllout_div); + + return (pllsrc_freq * plln_mul) / + (pllm_div * pllout_div); +} + +static uint32_t get_sysclk_frequency(void) +{ +#if defined(STM32_SYSCLK_SRC_PLL) + return get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_R_DIVISOR); +#elif defined(STM32_SYSCLK_SRC_MSIS) + return get_msis_frequency(); +#elif defined(STM32_SYSCLK_SRC_HSE + return STM32_HSE_FREQ; +#elif defined(STM32_SYSCLK_SRC_HSI)) { + return STM32_HSI_FREQ; +#else + __ASSERT(0, "No SYSCLK Source configured"); + return 0; +#endif + +} + +/** @brief Verifies clock is part of active clock configuration */ +static int enabled_clock(uint32_t src_clk) +{ + if ((src_clk == STM32_SRC_SYSCLK) || + ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) || + ((src_clk == STM32_SRC_HSI16) && IS_ENABLED(STM32_HSI_ENABLED)) || + ((src_clk == STM32_SRC_LSE) && IS_ENABLED(STM32_LSE_ENABLED)) || + ((src_clk == STM32_SRC_LSI) && IS_ENABLED(STM32_LSI_ENABLED)) || + ((src_clk == STM32_SRC_MSIS) && IS_ENABLED(STM32_MSIS_ENABLED)) || + ((src_clk == STM32_SRC_MSIK) && IS_ENABLED(STM32_MSIK_ENABLED)) || + ((src_clk == STM32_SRC_PLL1_P) && IS_ENABLED(STM32_PLL_P_ENABLED)) || + ((src_clk == STM32_SRC_PLL1_Q) && IS_ENABLED(STM32_PLL_Q_ENABLED)) || + ((src_clk == STM32_SRC_PLL1_R) && IS_ENABLED(STM32_PLL_R_ENABLED))) { + return 0; + } + + return -ENOTSUP; +} + static inline int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) { @@ -115,6 +166,35 @@ static inline int stm32_clock_control_off(const struct device *dev, return 0; } +static inline int stm32_clock_control_configure(const struct device *dev, + clock_control_subsys_t sub_system, + void *data) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + volatile uint32_t *reg; + uint32_t reg_val, dt_val; + int err; + + ARG_UNUSED(dev); + ARG_UNUSED(data); + + err = enabled_clock(pclken->bus); + if (err < 0) { + /* Attempt to configure a src clock not available or not valid */ + return err; + } + + dt_val = STM32_CLOCK_VAL_GET(pclken->enr) << + STM32_CLOCK_SHIFT_GET(pclken->enr); + reg = (uint32_t *)(DT_REG_ADDR(DT_NODELABEL(rcc)) + + STM32_CLOCK_REG_GET(pclken->enr)); + reg_val = *reg; + reg_val |= dt_val; + *reg = reg_val; + + return 0; +} + static int stm32_clock_control_get_subsys_rate(const struct device *dev, clock_control_subsys_t sys, uint32_t *rate) @@ -156,6 +236,60 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, case STM32_CLOCK_BUS_APB3: *rate = apb3_clock; break; + case STM32_SRC_SYSCLK: + *rate = get_sysclk_frequency(); + break; +#if defined(STM32_HSI_ENABLED) + case STM32_SRC_HSI16: + *rate = STM32_HSI_FREQ; + break; +#endif /* STM32_HSI_ENABLED */ +#if defined(STM32_MSIS_ENABLED) + case STM32_SRC_MSIS: + *rate = get_msis_frequency(); + break; +#endif /* STM32_MSIS_ENABLED */ +#if defined(STM32_MSIK_ENABLED) + case STM32_SRC_MSIK: + *rate = __LL_RCC_CALC_MSIK_FREQ(LL_RCC_MSIRANGESEL_RUN, + STM32_MSIK_RANGE << RCC_ICSCR1_MSIKRANGE_Pos); + break; +#endif /* STM32_MSIK_ENABLED */ +#if defined(STM32_HSE_ENABLED) + case STM32_SRC_HSE: + *rate = STM32_HSE_FREQ; + break; +#endif /* STM32_HSE_ENABLED */ +#if defined(STM32_LSE_ENABLED) + case STM32_SRC_LSE: + *rate = STM32_LSE_FREQ; + break; +#endif /* STM32_LSE_ENABLED */ +#if defined(STM32_LSI_ENABLED) + case STM32_SRC_LSI: + *rate = STM32_LSI_FREQ; + break; +#endif /* STM32_LSI_ENABLED */ +#if defined(STM32_PLL_ENABLED) + case STM32_SRC_PLL1_P: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_P_DIVISOR); + break; + case STM32_SRC_PLL1_Q: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_Q_DIVISOR); + break; + case STM32_SRC_PLL1_R: + *rate = get_pllout_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_R_DIVISOR); + break; +#endif /* STM32_PLL_ENABLED */ default: return -ENOTSUP; } @@ -167,6 +301,7 @@ static struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, + .configure = stm32_clock_control_configure, }; __unused diff --git a/drivers/clock_control/clock_stm32_mux.c b/drivers/clock_control/clock_stm32_mux.c new file mode 100644 index 0000000000000..1e63161d71118 --- /dev/null +++ b/drivers/clock_control/clock_stm32_mux.c @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2022, Linaro Ltd + * + */ + +#include +#include +#include + +#include +#include + +#define DT_DRV_COMPAT st_stm32_clock_mux + +LOG_MODULE_REGISTER(clock_mux, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + + +struct stm32_clk_mux_config { + const struct stm32_pclken pclken; +}; + +static int stm32_clk_mux_init(const struct device *dev) +{ + const struct stm32_clk_mux_config *cfg = dev->config; + + if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken) != 0) { + LOG_ERR("Could not enable clock mux"); + return -EIO; + } + + return 0; +} + +#define STM32_MUX_CLK_INIT(id) \ + \ +static const struct stm32_clk_mux_config stm32_clk_mux_cfg_##id = { \ + .pclken = STM32_INST_CLOCK_INFO(id, 0) \ +}; \ + \ +DEVICE_DT_INST_DEFINE(id, &stm32_clk_mux_init, NULL, \ + NULL, &stm32_clk_mux_cfg_##id, \ + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS,\ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(STM32_MUX_CLK_INIT) diff --git a/drivers/clock_control/clock_stm32f0_f3.c b/drivers/clock_control/clock_stm32f0_f3.c index f4bafff3d30ce..5b9aa0d6e21d7 100644 --- a/drivers/clock_control/clock_stm32f0_f3.c +++ b/drivers/clock_control/clock_stm32f0_f3.c @@ -15,13 +15,13 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /** * @brief Set up pll configuration */ -int config_pll_sysclock(void) +__unused +void config_pll_sysclock(void) { uint32_t pll_source, pll_mul, pll_div; @@ -59,7 +59,7 @@ int config_pll_sysclock(void) } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { pll_source = LL_RCC_PLLSOURCE_HSI; } else { - return -ENOTSUP; + __ASSERT(0, "Invalid source"); } LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul, pll_div); @@ -70,13 +70,71 @@ int config_pll_sysclock(void) } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { pll_source = LL_RCC_PLLSOURCE_HSI_DIV_2; } else { - return -ENOTSUP; + __ASSERT(0, "Invalid source"); } LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul); #endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ +} + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + uint32_t pll_input_freq, pll_mul, pll_div; + + /* + * PLL MUL + * 2 -> LL_RCC_PLL_MUL_2 -> 0x00000000 + * 3 -> LL_RCC_PLL_MUL_3 -> 0x00040000 + * 4 -> LL_RCC_PLL_MUL_4 -> 0x00080000 + * ... + * 16 -> LL_RCC_PLL_MUL_16 -> 0x00380000 + */ + pll_mul = ((STM32_PLL_MULTIPLIER - 2) << RCC_CFGR_PLLMUL_Pos); - return 0; + /* + * PLL PREDIV + * 1 -> LL_RCC_PREDIV_DIV_1 -> 0x00000000 + * 2 -> LL_RCC_PREDIV_DIV_2 -> 0x00000001 + * 3 -> LL_RCC_PREDIV_DIV_3 -> 0x00000002 + * ... + * 16 -> LL_RCC_PREDIV_DIV_16 -> 0x0000000F + */ + pll_div = STM32_PLL_PREDIV - 1; + +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + /* + * PREDIV1 support is a specific RCC configuration present on + * following SoCs: STM32F04xx, STM32F07xx, STM32F09xx, + * STM32F030xC, STM32F302xE, STM32F303xE and STM32F39xx + * cf Reference manual for more details + */ + + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + pll_input_freq = STM32_HSE_FREQ; + } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + pll_input_freq = STM32_HSI_FREQ; + } else { + return 0; + } + + return __LL_RCC_CALC_PLLCLK_FREQ(pll_input_freq, pll_mul, pll_div); +#else + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + pll_input_freq = STM32_HSE_FREQ; + } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + pll_input_freq = STM32_HSI_FREQ / 2; + } else { + return 0; + } + + return __LL_RCC_CALC_PLLCLK_FREQ(pll_input_freq, pll_mul); +#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ } #endif /* STM32_SYSCLK_SRC_PLL */ diff --git a/drivers/clock_control/clock_stm32f1.c b/drivers/clock_control/clock_stm32f1.c index 41ff680e1f7b1..879bd86c01483 100644 --- a/drivers/clock_control/clock_stm32f1.c +++ b/drivers/clock_control/clock_stm32f1.c @@ -15,8 +15,8 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL + /* * Select PLL source for STM32F1 Connectivity line devices (STM32F105xx and * STM32F107xx). @@ -26,7 +26,8 @@ /** * @brief Set up pll configuration */ -int config_pll_sysclock(void) +__unused +void config_pll_sysclock(void) { uint32_t pll_source, pll_mul, pll_div; @@ -88,13 +89,12 @@ int config_pll_sysclock(void) pll_source = LL_RCC_PLLSOURCE_PLL2 | pll_div; #endif } else { - return -ENOTSUP; + __ASSERT(0, "Invalid source"); } LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul); - - return 0; } + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index 02ceccf8ddf03..7475fb246fc49 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -15,7 +15,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up division factors values */ @@ -26,29 +25,45 @@ #define pllp(v) z_pllp(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_m, pll_n, pll_p; - - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pllm(STM32_PLL_M_DIVISOR); - pll_p = pllp(STM32_PLL_P_DIVISOR); - - /* Configure PLL source */ if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; + return LL_RCC_PLLSOURCE_HSI; } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; + return LL_RCC_PLLSOURCE_HSE; } - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_p); - + __ASSERT(0, "Invalid source"); return 0; } + +/** + * @brief Set up pll configuration + */ +__unused +void config_pll_sysclock(void) +{ + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllp(STM32_PLL_P_DIVISOR)); +} + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllp(STM32_PLL_P_DIVISOR)); +} + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32g0.c b/drivers/clock_control/clock_stm32g0.c index c707f3fd35d9d..d32646a3a9492 100644 --- a/drivers/clock_control/clock_stm32g0.c +++ b/drivers/clock_control/clock_stm32g0.c @@ -16,7 +16,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up multiplication and division factors values */ @@ -27,31 +26,49 @@ #define pllr(v) z_pllr(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_m, pll_n, pll_r; - - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pll_div(STM32_PLL_M_DIVISOR); - pll_r = pllr(STM32_PLL_R_DIVISOR); - /* Configure PLL source */ if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; + return LL_RCC_PLLSOURCE_HSI; } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; + return LL_RCC_PLLSOURCE_HSE; } - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_r); + __ASSERT(0, "Invalid source"); + return 0; +} + +/** + * @brief Set up pll configuration + */ +__unused +void config_pll_sysclock(void) +{ + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pll_div(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); LL_RCC_PLL_EnableDomain_SYS(); +} - return 0; + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pll_div(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); } + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32g4.c b/drivers/clock_control/clock_stm32g4.c index 8dfb3ccb1885c..2af65bf60418c 100644 --- a/drivers/clock_control/clock_stm32g4.c +++ b/drivers/clock_control/clock_stm32g4.c @@ -15,7 +15,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up division factors values */ @@ -26,36 +25,53 @@ #define pllr(v) z_pllr(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_m, pll_n, pll_r; + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + return LL_RCC_PLLSOURCE_HSI; + } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + return LL_RCC_PLLSOURCE_HSE; + } + + __ASSERT(0, "Invalid source"); + return 0; +} +/** + * @brief Set up pll configuration + */ +__unused +void config_pll_sysclock(void) +{ /* set power boost mode for sys clock greater than 150MHz */ if (sys_clock_hw_cycles_per_sec() >= MHZ(150)) { LL_PWR_EnableRange1BoostMode(); } - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pllm(STM32_PLL_M_DIVISOR); - pll_r = pllr(STM32_PLL_R_DIVISOR); - - /* Configure PLL source */ - if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; - } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; - } - - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_r); + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); LL_RCC_PLL_EnableDomain_SYS(); +} - return 0; +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); } + #endif /* STM32_SYSCLK_SRC_PLL */ /** @@ -65,24 +81,4 @@ void config_enable_default_clocks(void) { /* Enable the power interface clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); - -#if STM32_LSE_ENABLED - /* LSE belongs to the back-up domain, enable access.*/ - - /* Set the DBP bit in the Power control register 1 (PWR_CR1) */ - LL_PWR_EnableBkUpAccess(); - while (!LL_PWR_IsEnabledBkUpAccess()) { - /* Wait for Backup domain access */ - } - - /* Configure driving capability */ - LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos); - /* Enable LSE Oscillator (32.768 kHz) */ - LL_RCC_LSE_Enable(); - while (!LL_RCC_LSE_IsReady()) { - /* Wait for LSE ready */ - } - - LL_PWR_DisableBkUpAccess(); -#endif } diff --git a/drivers/clock_control/clock_stm32l0_l1.c b/drivers/clock_control/clock_stm32l0_l1.c index 82f17d342ba36..2a4d5e8ecbe77 100644 --- a/drivers/clock_control/clock_stm32l0_l1.c +++ b/drivers/clock_control/clock_stm32l0_l1.c @@ -15,7 +15,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up multiplication and division factors values */ @@ -26,29 +25,44 @@ #define pll_div(v) z_pll_div(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_mul, pll_div; - - pll_mul = pll_mul(STM32_PLL_MULTIPLIER); - pll_div = pll_div(STM32_PLL_DIVISOR); - /* Configure PLL source */ if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; + return LL_RCC_PLLSOURCE_HSI; } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; + return LL_RCC_PLLSOURCE_HSE; } - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul, pll_div); - + __ASSERT(0, "Invalid source"); return 0; } +/** + * @brief Set up pll configuration + */ +__unused +void config_pll_sysclock(void) +{ + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pll_mul(STM32_PLL_MULTIPLIER), + pll_div(STM32_PLL_DIVISOR)); +} + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pll_mul(STM32_PLL_MULTIPLIER), + pll_div(STM32_PLL_DIVISOR)); +} + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32l4_l5_wb_wl.c b/drivers/clock_control/clock_stm32l4_l5_wb_wl.c index 1ad33315254b2..0fa87a62521e6 100644 --- a/drivers/clock_control/clock_stm32l4_l5_wb_wl.c +++ b/drivers/clock_control/clock_stm32l4_l5_wb_wl.c @@ -15,7 +15,6 @@ #include #include #include "clock_stm32_ll_common.h" -#include "stm32_hsem.h" #if STM32_SYSCLK_SRC_PLL @@ -27,12 +26,29 @@ #define pllr(v) z_pllr(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_m, pll_n, pll_r; + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + return LL_RCC_PLLSOURCE_HSI; + } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + return LL_RCC_PLLSOURCE_HSE; + } else if (IS_ENABLED(STM32_PLL_SRC_MSI)) { + return LL_RCC_PLLSOURCE_MSI; + } + + __ASSERT(0, "Invalid source"); + return 0; +} +/** + * @brief Set up pll configuration + */ +void config_pll_sysclock(void) +{ #ifdef PWR_CR5_R1MODE /* set power boost mode for sys clock greater than 80MHz */ if (sys_clock_hw_cycles_per_sec() >= MHZ(80)) { @@ -40,27 +56,26 @@ int config_pll_sysclock(void) } #endif /* PWR_CR5_R1MODE */ - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pllm(STM32_PLL_M_DIVISOR); - pll_r = pllr(STM32_PLL_R_DIVISOR); - - /* Configure PLL source */ - if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; - } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else if (IS_ENABLED(STM32_PLL_SRC_MSI)) { - pll_source = LL_RCC_PLLSOURCE_MSI; - } else { - return -ENOTSUP; - } - - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_r); + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); LL_RCC_PLL_EnableDomain_SYS(); +} - return 0; +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); } + #endif /* STM32_SYSCLK_SRC_PLL */ /** @@ -72,33 +87,8 @@ void config_enable_default_clocks(void) /* Enable the power interface clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); #endif - -#if STM32_LSE_ENABLED - /* LSE belongs to the back-up domain, enable access.*/ - #if defined(CONFIG_SOC_SERIES_STM32WBX) /* HW semaphore Clock enable */ LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_HSEM); -#endif - z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); - - /* Set the DBP bit in the Power control register 1 (PWR_CR1) */ - LL_PWR_EnableBkUpAccess(); - while (!LL_PWR_IsEnabledBkUpAccess()) { - /* Wait for Backup domain access */ - } - - /* Configure driving capability */ - LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos); - /* Enable LSE Oscillator (32.768 kHz) */ - LL_RCC_LSE_Enable(); - while (!LL_RCC_LSE_IsReady()) { - /* Wait for LSE ready */ - } - - LL_PWR_DisableBkUpAccess(); - - z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); - #endif } diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index e747f17fa6d6d..7e3ca9a9a3e50 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -489,10 +489,18 @@ static int spi_stm32_configure(const struct device *dev, #endif } - if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &cfg->pclken, &clock) < 0) { - LOG_ERR("Failed call clock_control_get_rate"); - return -EIO; + if (IS_ENABLED(STM32_SPI_OPT_CLOCK_SUPPORT) && (cfg->pclk_len > 1)) { + if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[1], &clock) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[1])"); + return -EIO; + } + } else { + if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[0], &clock) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[0])"); + return -EIO; + } } for (br = 1 ; br <= ARRAY_SIZE(scaler) ; ++br) { @@ -860,10 +868,21 @@ static int spi_stm32_init(const struct device *dev) const struct spi_stm32_config *cfg = dev->config; int err; - if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &cfg->pclken) != 0) { + err = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[0]); + if (err < 0) { LOG_ERR("Could not enable SPI clock"); - return -EIO; + return err; + } + + if (IS_ENABLED(STM32_SPI_OPT_CLOCK_SUPPORT) && (cfg->pclk_len > 1)) { + err = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[1], + NULL); + if (err < 0) { + LOG_ERR("Could not select SPI source clock"); + return err; + } } if (!spi_stm32_is_subghzspi(dev)) { @@ -971,17 +990,20 @@ static void spi_stm32_irq_config_func_##id(const struct device *dev) \ #define STM32_SPI_USE_SUBGHZSPI_NSS_CONFIG(id) #endif + + #define STM32_SPI_INIT(id) \ STM32_SPI_IRQ_HANDLER_DECL(id); \ \ PINCTRL_DT_INST_DEFINE(id); \ \ +static const struct stm32_pclken pclken_##id[] = \ + STM32_DT_INST_CLOCKS(id);\ + \ static const struct spi_stm32_config spi_stm32_cfg_##id = { \ .spi = (SPI_TypeDef *) DT_INST_REG_ADDR(id), \ - .pclken = { \ - .enr = DT_INST_CLOCKS_CELL(id, bits), \ - .bus = DT_INST_CLOCKS_CELL(id, bus) \ - }, \ + .pclken = pclken_##id, \ + .pclk_len = DT_INST_NUM_CLOCKS(id), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \ STM32_SPI_IRQ_HANDLER_FUNC(id) \ STM32_SPI_USE_SUBGHZSPI_NSS_CONFIG(id) \ diff --git a/drivers/spi/spi_ll_stm32.h b/drivers/spi/spi_ll_stm32.h index 7d8206ee33359..969c0b9624c12 100644 --- a/drivers/spi/spi_ll_stm32.h +++ b/drivers/spi/spi_ll_stm32.h @@ -11,8 +11,15 @@ typedef void (*irq_config_func_t)(const struct device *port); +/* This symbol takes the value 1 if one of the device instances */ +/* is configured in dts with an optional clock */ +#if STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT +#define STM32_SPI_OPT_CLOCK_SUPPORT 1 +#else +#define STM32_SPI_OPT_CLOCK_SUPPORT 0 +#endif + struct spi_stm32_config { - struct stm32_pclken pclken; SPI_TypeDef *spi; const struct pinctrl_dev_config *pcfg; #ifdef CONFIG_SPI_STM32_INTERRUPT @@ -21,6 +28,8 @@ struct spi_stm32_config { #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_spi_subghz) bool use_subghzspi_nss; #endif + size_t pclk_len; + const struct stm32_pclken *pclken; }; #ifdef CONFIG_SPI_STM32_DMA diff --git a/dts/arm/st/f0/stm32f0.dtsi b/dts/arm/st/f0/stm32f0.dtsi index 94f94ebe59bc1..5d52ac4c51def 100644 --- a/dts/arm/st/f0/stm32f0.dtsi +++ b/dts/arm/st/f0/stm32f0.dtsi @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include #include diff --git a/dts/arm/st/f3/stm32f3.dtsi b/dts/arm/st/f3/stm32f3.dtsi index 7c314de369014..fae2459a7b835 100644 --- a/dts/arm/st/f3/stm32f3.dtsi +++ b/dts/arm/st/f3/stm32f3.dtsi @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include #include diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index 34c035f05b9ae..dcc808a234281 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -7,7 +7,7 @@ #include -#include +#include #include #include #include @@ -51,9 +51,8 @@ clk_lse: clk-lse { #clock-cells = <0>; - compatible = "st,stm32-lse-clock"; + compatible = "fixed-clock"; clock-frequency = <32768>; - driving-capability = <0>; status = "disabled"; }; @@ -354,7 +353,7 @@ }; can { - compatible = "bosch,m_can-base"; + compatible = "bosch,m-can-base"; #address-cells = <1>; #size-cells = <1>; std-filter-elements = <28>; diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 84ab931ef219e..cb42fe9b92ae2 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -92,6 +92,12 @@ reg = <2>; status = "disabled"; }; + + perck: perck { + #clock-cells = <0>; + compatible = "st,stm32-clock-mux"; + status = "disabled"; + }; }; soc { diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 016f7f236720b..65addda4895c0 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -62,6 +62,13 @@ status = "disabled"; }; + clk_msik: clk-msik { + #clock-cells = <0>; + compatible = "st,stm32u5-msi-clock"; + msi-range = <4>; /* 4MHz (reset value) */ + status = "disabled"; + }; + clk_lse: clk-lse { #clock-cells = <0>; compatible = "st,stm32-lse-clock"; diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index aec81c3edff7c..5bea126818ec7 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include #include diff --git a/dts/bindings/clock/st,stm32-clock-mux.yaml b/dts/bindings/clock/st,stm32-clock-mux.yaml new file mode 100644 index 0000000000000..49257e276bb5e --- /dev/null +++ b/dts/bindings/clock/st,stm32-clock-mux.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2022, Linaro ltd +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32 Clock multiplexer + Describes a clock multiplexer, such as per_ck on STM32H7 or + CLK48 on STM32L5. + The only property of this node is to select a clock input. + For instance: + &perck { + clocks = <&rcc STM32_SRC_HSI_KER CKPER_SEL(0)>; + status = "okay"; + }; + +compatible: "st,stm32-clock-mux" + +include: + - name: base.yaml + property-allowlist: + - status + - compatible + - clocks diff --git a/dts/bindings/clock/st,stm32-rcc.yaml b/dts/bindings/clock/st,stm32-rcc.yaml index 1658dd471a4a4..b66c878dadf23 100644 --- a/dts/bindings/clock/st,stm32-rcc.yaml +++ b/dts/bindings/clock/st,stm32-rcc.yaml @@ -37,6 +37,20 @@ description: | the bus controlling the peripheral and the second index specifies the bit used to control the peripheral clock in that bus register. + Specifying an alternate clock source: + + Specifying an alternate source clock could be done by adding a clock specifier to the + clock property: + ... { + ... + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00000020>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + ... + } + In this example I2C1 device is assigned HSI as clock source. + It is device driver's responsibility to querry and use clock source information in + accordance with clock_control API specifications. + compatible: "st,stm32-rcc" include: [clock-controller.yaml, base.yaml] diff --git a/include/zephyr/drivers/clock_control.h b/include/zephyr/drivers/clock_control.h index 9f790baa41dff..df357de22bd06 100644 --- a/include/zephyr/drivers/clock_control.h +++ b/include/zephyr/drivers/clock_control.h @@ -92,6 +92,10 @@ typedef int (*clock_control_set)(const struct device *dev, clock_control_subsys_t sys, clock_control_subsys_rate_t rate); +typedef int (*clock_control_configure_fn)(const struct device *dev, + clock_control_subsys_t sys, + void *data); + struct clock_control_driver_api { clock_control on; clock_control off; @@ -99,6 +103,7 @@ struct clock_control_driver_api { clock_control_get get_rate; clock_control_get_status_fn get_status; clock_control_set set_rate; + clock_control_configure_fn configure; }; /** @@ -270,6 +275,45 @@ static inline int clock_control_set_rate(const struct device *dev, return api->set_rate(dev, sys, rate); } +/** + * @brief Configure a source clock + * + * This function is non-blocking and can be called from any context. + * On success, the selected clock is configured as per caller's request. + * + * It is caller's responsibility to ensure that subsequent calls to the API + * provide the right information to allows clock_control driver to perform + * the right action (such as using the right clock source on clock_control_get_rate + * call). + * + * @p data is implementation specific and could be used to convey + * supplementary information required for expected clock configuration. + * + * @param dev Device structure whose driver controls the clock + * @param sys Opaque data representing the clock + * @param data Opaque data providing additional input for clock configuration + * + * @retval 0 On success + * @retval -ENOSYS If the device driver does not implement this call + * @retval -errno Other negative errno on failure. + */ +static inline int clock_control_configure(const struct device *dev, + clock_control_subsys_t sys, + void *data) +{ + if (!device_is_ready(dev)) { + return -ENODEV; + } + + const struct clock_control_driver_api *api = + (const struct clock_control_driver_api *)dev->api; + + if (api->configure == NULL) { + return -ENOSYS; + } + + return api->configure(dev, sys, data); +} #ifdef __cplusplus } diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index 7a2f80b958ae7..a586cd1820c52 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -11,25 +11,29 @@ #include -#if defined(CONFIG_SOC_SERIES_STM32F0X) || \ - defined(CONFIG_SOC_SERIES_STM32F1X) || \ - defined(CONFIG_SOC_SERIES_STM32F3X) +#if defined(CONFIG_SOC_SERIES_STM32F0X) +#include +#elif defined(CONFIG_SOC_SERIES_STM32F1X) #include +#elif defined(CONFIG_SOC_SERIES_STM32F3X) +#include #elif defined(CONFIG_SOC_SERIES_STM32F2X) || \ defined(CONFIG_SOC_SERIES_STM32F4X) || \ defined(CONFIG_SOC_SERIES_STM32F7X) #include #elif defined(CONFIG_SOC_SERIES_STM32G0X) #include +#elif defined(CONFIG_SOC_SERIES_STM32G4X) +#include #elif defined(CONFIG_SOC_SERIES_STM32L0X) #include #elif defined(CONFIG_SOC_SERIES_STM32L1X) #include -#elif defined(CONFIG_SOC_SERIES_STM32G4X) || \ - defined(CONFIG_SOC_SERIES_STM32L4X) || \ - defined(CONFIG_SOC_SERIES_STM32L5X) || \ - defined(CONFIG_SOC_SERIES_STM32WBX) +#elif defined(CONFIG_SOC_SERIES_STM32L4X) || \ + defined(CONFIG_SOC_SERIES_STM32L5X) #include +#elif defined(CONFIG_SOC_SERIES_STM32WBX) +#include #elif defined(CONFIG_SOC_SERIES_STM32WLX) #include #elif defined(CONFIG_SOC_SERIES_STM32H7X) @@ -264,6 +268,10 @@ #define STM32_HSE_FREQ 0 #endif +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(perck), st_stm32_clock_mux, okay) +#define STM32_CKPER_ENABLED 1 +#endif + /** Driver structure definition */ struct stm32_pclken { @@ -271,4 +279,70 @@ struct stm32_pclken { uint32_t enr; }; +/** Device tree clocks helpers */ + +#define STM32_CLOCK_INFO(clk_index, id) \ + { \ + .enr = DT_CLOCKS_CELL_BY_IDX(DT_NODELABEL(id), clk_index, bits),\ + .bus = DT_CLOCKS_CELL_BY_IDX(DT_NODELABEL(id), clk_index, bus) \ + } +#define STM32_DT_CLOCKS(id) \ + { \ + LISTIFY(DT_NUM_CLOCKS(DT_NODELABEL(id)), \ + STM32_CLOCK_INFO, (,), id) \ + } + +#define STM32_INST_CLOCK_INFO(clk_index, inst) \ + { \ + .enr = DT_INST_CLOCKS_CELL_BY_IDX(inst, clk_index, bits), \ + .bus = DT_INST_CLOCKS_CELL_BY_IDX(inst, clk_index, bus) \ + } +#define STM32_DT_INST_CLOCKS(inst) \ + { \ + LISTIFY(DT_INST_NUM_CLOCKS(inst), \ + STM32_INST_CLOCK_INFO, (,), inst) \ + } + +#define STM32_OPT_CLOCK_INST_SUPPORT(inst) DT_INST_CLOCKS_HAS_IDX(inst, 1) || +#define STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT \ + (DT_INST_FOREACH_STATUS_OKAY(STM32_OPT_CLOCK_INST_SUPPORT) 0) + +#define STM32_OPT_CLOCK_SUPPORT(id) DT_CLOCKS_HAS_IDX(DT_NODELABEL(id), 1) || +#define STM32_DT_DEV_OPT_CLOCK_SUPPORT \ + (DT_FOREACH_STATUS_OKAY(STM32_OPT_CLOCK_SUPPORT) 0) + +/** Clock source binding accessors */ + +/** + * @brief Obtain register field from clock configuration. + * + * @param clock clock bit field value. + */ +#define STM32_CLOCK_REG_GET(clock) \ + (((clock) >> STM32_CLOCK_REG_SHIFT) & STM32_CLOCK_REG_MASK) + +/** + * @brief Obtain position field from clock configuration. + * + * @param clock Clock bit field value. + */ +#define STM32_CLOCK_SHIFT_GET(clock) \ + (((clock) >> STM32_CLOCK_SHIFT_SHIFT) & STM32_CLOCK_SHIFT_MASK) + +/** + * @brief Obtain mask field from clock configuration. + * + * @param clock Clock bit field value. + */ +#define STM32_CLOCK_MASK_GET(clock) \ + (((clock) >> STM32_CLOCK_MASK_SHIFT) & STM32_CLOCK_MASK_MASK) + +/** + * @brief Obtain value field from clock configuration. + * + * @param clock Clock bit field value. + */ +#define STM32_CLOCK_VAL_GET(clock) \ + (((clock) >> STM32_CLOCK_VAL_SHIFT) & STM32_CLOCK_VAL_MASK) + #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_STM32_CLOCK_CONTROL_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f0_clock.h b/include/zephyr/dt-bindings/clock/stm32f0_clock.h new file mode 100644 index 0000000000000..dd87ab60a4e34 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/stm32f0_clock.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F0_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F0_CLOCK_H_ + +/** Bus gatting clocks */ +#define STM32_CLOCK_BUS_AHB1 0x014 +#define STM32_CLOCK_BUS_APB2 0x018 +#define STM32_CLOCK_BUS_APB1 0x01c + +#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 +#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB1 + +/** Peripheral clock sources */ + +/** Fixed clocks */ +#define STM32_SRC_HSI 0x001 +#define STM32_SRC_LSE 0x002 +/* #define STM32_SRC_HSI48 0x003 */ +/** System clock */ +#define STM32_SRC_SYSCLK 0x004 +/** Bus clock */ +#define STM32_SRC_PCLK 0x005 +/** PLL clock */ +#define STM32_SRC_PLLCLK 0x006 + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSI +#define STM32_SRC_CLOCK_MAX STM32_SRC_PLLCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CFGRx register offset + * @param shift Position within RCC_CFGRx. + * @param mask Mask for the RCC_CFGRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CFGRx register offset */ +#define CFGR3_REG 0x30 + +/** @brief Device clk sources selection helpers */ +/** CFGR3 devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CFGR3_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 1, 4, CFGR3_REG) +#define CEC_SEL(val) STM32_CLOCK(val, 1, 6, CFGR3_REG) +#define USB_SEL(val) STM32_CLOCK(val, 1, 7, CFGR3_REG) +#define ADC_SEL(val) STM32_CLOCK(val, 1, 8, CFGR3_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 16, CFGR3_REG) +#define USART3_SEL(val) STM32_CLOCK(val, 3, 18, CFGR3_REG) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f3_clock.h b/include/zephyr/dt-bindings/clock/stm32f3_clock.h new file mode 100644 index 0000000000000..69621d3e4bc7c --- /dev/null +++ b/include/zephyr/dt-bindings/clock/stm32f3_clock.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F3_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F3_CLOCK_H_ + +/** Bus gatting clocks */ +#define STM32_CLOCK_BUS_AHB1 0x014 +#define STM32_CLOCK_BUS_APB2 0x018 +#define STM32_CLOCK_BUS_APB1 0x01c + +#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 +#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB1 + +/** Peripheral clock sources */ +/* RM0316, §9.4.13 Clock configuration register (RCC_CFGR3) */ + +/** Fixed clocks */ +#define STM32_SRC_HSI 0x001 +#define STM32_SRC_LSE 0x002 +/* #define STM32_SRC_HSI48 0x003 */ +/** System clock */ +#define STM32_SRC_SYSCLK 0x004 +/** Bus clock */ +#define STM32_SRC_PCLK 0x005 +/** PLL clock */ +#define STM32_SRC_PLLCLK 0x006 + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSI +#define STM32_SRC_CLOCK_MAX STM32_SRC_PLLCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CFGRx register offset + * @param shift Position within RCC_CFGRx. + * @param mask Mask for the RCC_CFGRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CFGRx register offset */ +#define CFGR3_REG 0x30 + +/** @brief Device clk sources selection helpers) */ +/** CFGR3 devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CFGR3_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 1, 4, CFGR3_REG) +#define I2C2_SEL(val) STM32_CLOCK(val, 1, 5, CFGR3_REG) +#define I2C3_SEL(val) STM32_CLOCK(val, 1, 6, CFGR3_REG) +#define TIM1_SEL(val) STM32_CLOCK(val, 1, 8, CFGR3_REG) +#define TIM8_SEL(val) STM32_CLOCK(val, 1, 9, CFGR3_REG) +#define TIM15_SEL(val) STM32_CLOCK(val, 1, 10, CFGR3_REG) +#define TIM16_SEL(val) STM32_CLOCK(val, 1, 11, CFGR3_REG) +#define TIM17_SEL(val) STM32_CLOCK(val, 1, 13, CFGR3_REG) +#define TIM20_SEL(val) STM32_CLOCK(val, 1, 15, CFGR3_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 16, CFGR3_REG) +#define USART3_SEL(val) STM32_CLOCK(val, 3, 18, CFGR3_REG) +#define USART4_SEL(val) STM32_CLOCK(val, 3, 20, CFGR3_REG) +#define USART5_SEL(val) STM32_CLOCK(val, 3, 22, CFGR3_REG) +#define TIM2_SEL(val) STM32_CLOCK(val, 1, 24, CFGR3_REG) +#define TIM3_4_SEL(val) STM32_CLOCK(val, 1, 25, CFGR3_REG) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F3_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32g0_clock.h b/include/zephyr/dt-bindings/clock/stm32g0_clock.h index 37fc66a004012..c9187a1649641 100644 --- a/include/zephyr/dt-bindings/clock/stm32g0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32g0_clock.h @@ -6,8 +6,6 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G0_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G0_CLOCK_H_ -/** Peripheral clock sources */ - /** Bus clocks */ #define STM32_CLOCK_BUS_IOP 0x034 #define STM32_CLOCK_BUS_AHB1 0x038 @@ -17,4 +15,80 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_IOP #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB1 +/** Peripheral clock sources */ +/* RM0444, §5.4.21/22 Clock configuration register (RCC_CCIPRx) */ + +/** Fixed clocks */ +#define STM32_SRC_HSI 0x001 +#define STM32_SRC_MSI 0x002 +#define STM32_SRC_LSE 0x003 +#define STM32_SRC_LSI 0x004 +/** System clock */ +#define STM32_SRC_SYSCLK 0x005 +/** Peripheral bus clock */ +#define STM32_SRC_PCLK 0x006 +/** PLL clock */ +#define STM32_SRC_PLLCLK 0x007 + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSI +#define STM32_SRC_CLOCK_MAX STM32_SRC_PLLCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CCIPR register offset */ +#define CCIPR_REG 0x54 +#define CCIPR2_REG 0x58 + +/** @brief Device clk sources selection helpers */ +/** CCIPR devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR_REG) +#define USART3_SEL(val) STM32_CLOCK(val, 3, 4, CCIPR_REG) +#define CEC_SEL(val) STM32_CLOCK(val, 1, 6, CCIPR_REG) +#define LPUART2_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR_REG) +#define I2C2_I2S1_SEL(val) STM32_CLOCK(val, 3, 14, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR_REG) +#define TIM1_SEL(val) STM32_CLOCK(val, 1, 22, CCIPR_REG) +#define TIM15_SEL(val) STM32_CLOCK(val, 1, 24, CCIPR_REG) +#define RNG_SEL(val) STM32_CLOCK(val, 3, 26, CCIPR_REG) +#define ADC_SEL(val) STM32_CLOCK(val, 3, 30, CCIPR_REG) +/** CCIPR2 devices */ +#define I2S1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR2_REG) +#define I2S2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR2_REG) +#define FDCAN_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR2_REG) +#define USB_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR2_REG) + + + + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32g4_clock.h b/include/zephyr/dt-bindings/clock/stm32g4_clock.h new file mode 100644 index 0000000000000..48600391f05b5 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/stm32g4_clock.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G4_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G4_CLOCK_H_ + +/** Bus clocks */ +#define STM32_CLOCK_BUS_AHB1 0x048 +#define STM32_CLOCK_BUS_AHB2 0x04c +#define STM32_CLOCK_BUS_AHB3 0x050 +#define STM32_CLOCK_BUS_APB1 0x058 +#define STM32_CLOCK_BUS_APB1_2 0x05c +#define STM32_CLOCK_BUS_APB2 0x060 + +#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 +#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB2 + +/** Peripheral clock sources */ +/* RM0440, § Clock configuration register (RCC_CCIPRx) */ + +/** Fixed clocks */ +#define STM32_SRC_HSI 0x001 +/* #define STM32_SRC_HSI48 0x002 */ +#define STM32_SRC_LSE 0x003 +#define STM32_SRC_LSI 0x004 +#define STM32_SRC_MSI 0x005 +/** System clock */ +#define STM32_SRC_SYSCLK 0x006 +/** Bus clock */ +#define STM32_SRC_PCLK 0x007 +/** PLL clocks */ +#define STM32_SRC_PLLCLK 0x008 +/* TODO: PLLSAI clocks */ + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSI +#define STM32_SRC_CLOCK_MAX STM32_SRC_PLLCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CCIPR register offset */ +#define CCIPR_REG 0x88 +#define CCIPR2_REG 0x9C + +/** @brief Device clk sources selection helpers */ +/** CCIPR devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR_REG) +#define USART3_SEL(val) STM32_CLOCK(val, 3, 4, CCIPR_REG) +#define USART4_SEL(val) STM32_CLOCK(val, 3, 6, CCIPR_REG) +#define LPUART1_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR_REG) +#define I2C2_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR_REG) +#define I2C3_SEL(val) STM32_CLOCK(val, 3, 14, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 16, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_CLOCK(val, 3, 18, CCIPR_REG) +#define LPTIM3_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR_REG) +#define SAI1_SEL(val) STM32_CLOCK(val, 3, 22, CCIPR_REG) +#define SAI2_SEL(val) STM32_CLOCK(val, 3, 24, CCIPR_REG) +#define CLK48_SEL(val) STM32_CLOCK(val, 3, 26, CCIPR_REG) +#define ADC12_SEL(val) STM32_CLOCK(val, 3, 28, CCIPR_REG) +#define ADC34_SEL(val) STM32_CLOCK(val, 3, 30, CCIPR_REG) +/** CCIPR2 devices */ +#define I2C4_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR2_REG) +#define QSPI_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR2_REG) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G4_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32h7_clock.h b/include/zephyr/dt-bindings/clock/stm32h7_clock.h index 608bc2182814f..ec330b532b639 100644 --- a/include/zephyr/dt-bindings/clock/stm32h7_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32h7_clock.h @@ -6,18 +6,127 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7_CLOCK_H_ -/* clock bus references */ -#define STM32_CLOCK_BUS_AHB3 0x134 -#define STM32_CLOCK_BUS_AHB1 0x138 -#define STM32_CLOCK_BUS_AHB2 0x13c -#define STM32_CLOCK_BUS_AHB4 0x140 -#define STM32_CLOCK_BUS_APB3 0x144 -#define STM32_CLOCK_BUS_APB1 0x148 -#define STM32_CLOCK_BUS_APB1_2 0x14c -#define STM32_CLOCK_BUS_APB2 0x150 -#define STM32_CLOCK_BUS_APB4 0x154 +/** Peripheral clock sources */ + +/* RM0468, Table 56 Kernel clock dictribution summary */ + +/** PLL outputs */ +#define STM32_SRC_PLL1_P 0x001 +#define STM32_SRC_PLL1_Q 0x002 +#define STM32_SRC_PLL1_R 0x003 +/** PLL2 not yet supported */ +/* #define STM32_SRC_PLL2_P 0x004 */ +/* #define STM32_SRC_PLL2_Q 0x005 */ +/* #define STM32_SRC_PLL2_R 0x006 */ +#define STM32_SRC_PLL3_P 0x007 +#define STM32_SRC_PLL3_Q 0x008 +#define STM32_SRC_PLL3_R 0x009 +/** Oscillators */ +#define STM32_SRC_HSE 0x00A +#define STM32_SRC_LSE 0x00B +#define STM32_SRC_LSI 0x00C +/** Oscillators not yet supported */ +/* #define STM32_SRC_HSI48 0x00D */ +#define STM32_SRC_HSI_KER 0x00E /* HSI + HSIKERON */ +#define STM32_SRC_CSI_KER 0x00F /* CSI + CSIKERON */ +/** Core clock */ +#define STM32_SRC_SYSCLK 0x010 +/** Others: Not yet supported */ +/* #define STM32_SRC_I2SCKIN 0x011 */ +/* #define STM32_SRC_SPDIFRX 0x012 */ +/** Clock muxes */ +#define STM32_SRC_CKPER 0x013 + +#define STM32_SRC_CLOCK_MIN STM32_SRC_PLL1_P +#define STM32_SRC_CLOCK_MAX STM32_SRC_CKPER + +/** Bus clocks */ +#define STM32_CLOCK_BUS_AHB3 0x0D4 +#define STM32_CLOCK_BUS_AHB1 0x0D8 +#define STM32_CLOCK_BUS_AHB2 0x0DC +#define STM32_CLOCK_BUS_AHB4 0x0E0 +#define STM32_CLOCK_BUS_APB3 0x0E4 +#define STM32_CLOCK_BUS_APB1 0x0E8 +#define STM32_CLOCK_BUS_APB1_2 0x0EC +#define STM32_CLOCK_BUS_APB2 0x0F0 +#define STM32_CLOCK_BUS_APB4 0x0F4 +/** Alias D1/2/3 domains clocks */ /* TBD: To remove ? */ +#define STM32_SRC_PCLK1 STM32_CLOCK_BUS_APB1 +#define STM32_SRC_PCLK2 STM32_CLOCK_BUS_APB2 +#define STM32_SRC_HCLK3 STM32_CLOCK_BUS_AHB3 +#define STM32_SRC_PCLK3 STM32_CLOCK_BUS_APB3 +#define STM32_SRC_PCLK4 STM32_CLOCK_BUS_APB4 #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB3 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB4 +/** + * @brief STM32H7 clock configuration bit field. + * + * - reg (0/1) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..3) [ 16 : 18 ] + * + * @param reg RCC_DxCCIP register offset + * @param shift Position within RCC_DxCCIP. + * @param mask Mask for the RCC_DxCCIP field. + * @param val Clock value (0, 1, 2 or 3). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_DxCCIP register offset (RM0399.pdf) */ +#define D1CCIPR_REG 0x4C +#define D2CCIP1R_REG 0x50 +#define D2CCIP2R_REG 0x54 +#define D3CCIPR_REG 0x58 + +/** @brief Device clk sources selection helpers (RM0399.pdf) */ +/** D1CCIPR devices */ +#define FMC_SEL(val) STM32_CLOCK(val, 3, 0, D1CCIPR_REG) +#define QSPI_SEL(val) STM32_CLOCK(val, 3, 4, D1CCIPR_REG) +#define DSI_SEL(val) STM32_CLOCK(val, 1, 8, D1CCIPR_REG) +#define SDMMC_SEL(val) STM32_CLOCK(val, 1, 16, D1CCIPR_REG) +#define CKPER_SEL(val) STM32_CLOCK(val, 3, 28, D1CCIPR_REG) +/** D2CCIP1R devices */ +#define SAI1_SEL(val) STM32_CLOCK(val, 7, 0, D2CCIP1R_REG) +#define SAI23_SEL(val) STM32_CLOCK(val, 7, 6, D2CCIP1R_REG) +#define SPI123_SEL(val) STM32_CLOCK(val, 7, 12, D2CCIP1R_REG) +#define SPI45_SEL(val) STM32_CLOCK(val, 7, 16, D2CCIP1R_REG) +#define SPDIF_SEL(val) STM32_CLOCK(val, 3, 20, D2CCIP1R_REG) +#define DFSDM1_SEL(val) STM32_CLOCK(val, 1, 24, D2CCIP1R_REG) +#define FDCAN_SEL(val) STM32_CLOCK(val, 3, 28, D2CCIP1R_REG) +#define SWP_SEL(val) STM32_CLOCK(val, 1, 31, D2CCIP1R_REG) +/** D2CCIP2R devices */ +#define USART2345678_SEL(val) STM32_CLOCK(val, 7, 0, D2CCIP2R_REG) +#define USART16_SEL(val) STM32_CLOCK(val, 7, 3, D2CCIP2R_REG) +#define RNG_SEL(val) STM32_CLOCK(val, 3, 8, D2CCIP2R_REG) +#define I2C123_SEL(val) STM32_CLOCK(val, 3, 12, D2CCIP2R_REG) +#define USB_SEL(val) STM32_CLOCK(val, 3, 20, D2CCIP2R_REG) +#define CEC_SEL(val) STM32_CLOCK(val, 3, 22, D2CCIP2R_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 7, 28, D2CCIP2R_REG) +/** D3CCIPR devices */ +#define LPUART1_SEL(val) STM32_CLOCK(val, 7, 0, D3CCIPR_REG) +#define I2C4_SEL(val) STM32_CLOCK(val, 3, 8, D3CCIPR_REG) +#define LPTIM2_SEL(val) STM32_CLOCK(val, 7, 10, D3CCIPR_REG) +#define LPTIM345_SEL(val) STM32_CLOCK(val, 7, 13, D3CCIPR_REG) +#define ADC_SEL(val) STM32_CLOCK(val, 3, 16, D3CCIPR_REG) +#define SAI4A_SEL(val) STM32_CLOCK(val, 7, 21, D3CCIPR_REG) +#define SAI4B_SEL(val) STM32_CLOCK(val, 7, 24, D3CCIPR_REG) +#define SPI6_SEL(val) STM32_CLOCK(val, 7, 28, D3CCIPR_REG) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32l0_clock.h b/include/zephyr/dt-bindings/clock/stm32l0_clock.h index b6e8b681d7d8b..647c3cd12ec75 100644 --- a/include/zephyr/dt-bindings/clock/stm32l0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32l0_clock.h @@ -6,9 +6,7 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L0_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L0_CLOCK_H_ -/** Peripheral clock sources */ - -/** Bus clocks */ +/** Bus gatting clocks */ #define STM32_CLOCK_BUS_IOP 0x02c #define STM32_CLOCK_BUS_AHB1 0x030 #define STM32_CLOCK_BUS_APB2 0x034 @@ -17,4 +15,62 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_IOP #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB1 +/** Peripheral clock sources */ +/* RM0367, §7.3.20 Clock configuration register (RCC_CCIPR) */ + +/** Fixed clocks */ +#define STM32_SRC_HSE 0x001 +#define STM32_SRC_LSE 0x002 +#define STM32_SRC_LSI 0x003 +#define STM32_SRC_HSI 0x004 +/** System clock */ +#define STM32_SRC_SYSCLK 0x005 +/** Bus clock */ +#define STM32_SRC_PCLK 0x006 + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSE +#define STM32_SRC_CLOCK_MAX STM32_SRC_PCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CCIPR register offset */ +#define CCIPR_REG 0x4C + +/** @brief Device clk sources selection helpers */ +/** CCIPR devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR_REG) +#define LPUART1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR_REG) +#define I2C3_SEL(val) STM32_CLOCK(val, 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 18, CCIPR_REG) +#define HSI48_SEL(val) STM32_CLOCK(val, 1, 26, CCIPR_REG) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32l1_clock.h b/include/zephyr/dt-bindings/clock/stm32l1_clock.h index 5fc6155527c1c..fb4ee16f6841c 100644 --- a/include/zephyr/dt-bindings/clock/stm32l1_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32l1_clock.h @@ -6,9 +6,7 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L1_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L1_CLOCK_H_ -/** Peripheral clock sources */ - -/** Bus clocks */ +/** Bus gatting clocks */ #define STM32_CLOCK_BUS_AHB1 0x01c #define STM32_CLOCK_BUS_APB2 0x020 #define STM32_CLOCK_BUS_APB1 0x024 @@ -16,4 +14,49 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB1 -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L1_CLOCK_H_ */ +/** Peripheral clock sources */ +/* RM0038.pdf, §6.3.14 Control/status register (RCC_CSR) */ + +/** Fixed clocks */ +#define STM32_SRC_HSE 0x001 +#define STM32_SRC_LSE 0x002 +#define STM32_SRC_LSI 0x003 + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSE +#define STM32_SRC_CLOCK_MAX STM32_SRC_LSI + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CSR register offset */ +#define CSR_REG 0x34 + +#define RTC_SEL(val) STM32_CLOCK(val, 3, 16, CSR_REG) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32l4_clock.h b/include/zephyr/dt-bindings/clock/stm32l4_clock.h index 71e51ec881a1f..eb572c9776b14 100644 --- a/include/zephyr/dt-bindings/clock/stm32l4_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32l4_clock.h @@ -6,8 +6,6 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L4_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L4_CLOCK_H_ -/** Peripheral clock sources */ - /** Bus clocks */ #define STM32_CLOCK_BUS_AHB1 0x048 #define STM32_CLOCK_BUS_AHB2 0x04c @@ -19,4 +17,86 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB2 +/** Peripheral clock sources */ +/* RM0351/RM0432/RM0438, § Clock configuration register (RCC_CCIPRx) */ + +/** Fixed clocks */ +#define STM32_SRC_HSI 0x001 +/* #define STM32_SRC_HSI48 0x002 */ +#define STM32_SRC_LSE 0x003 +#define STM32_SRC_LSI 0x004 +#define STM32_SRC_MSI 0x005 +/** System clock */ +#define STM32_SRC_SYSCLK 0x006 +/** Bus clock */ +#define STM32_SRC_PCLK 0x007 +/** PLL clocks */ +#define STM32_SRC_PLLCLK 0x008 +/* TODO: PLLSAI clocks */ + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSI +#define STM32_SRC_CLOCK_MAX STM32_SRC_PLLCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CCIPR register offset */ +#define CCIPR_REG 0x88 +#define CCIPR2_REG 0x9C + +/** @brief Device clk sources selection helpers */ +/** CCIPR devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR_REG) +#define USART3_SEL(val) STM32_CLOCK(val, 3, 4, CCIPR_REG) +#define UART4_SEL(val) STM32_CLOCK(val, 3, 6, CCIPR_REG) +#define UART5_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR_REG) +#define I2C2_SEL(val) STM32_CLOCK(val, 3, 14, CCIPR_REG) +#define I2C3_SEL(val) STM32_CLOCK(val, 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR_REG) +#define SAI1_SEL(val) STM32_CLOCK(val, 3, 22, CCIPR_REG) +#define SAI2_SEL(val) STM32_CLOCK(val, 3, 24, CCIPR_REG) +#define CLK48_SEL(val) STM32_CLOCK(val, 3, 26, CCIPR_REG) +#define ADC_SEL(val) STM32_CLOCK(val, 3, 28, CCIPR_REG) +#define SWPMI1_SEL(val) STM32_CLOCK(val, 1, 30, CCIPR_REG) +#define DFSDM1_SEL(val) STM32_CLOCK(val, 1, 31, CCIPR_REG) +/** CCIPR2 devices */ +#define I2C4_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR2_REG) +#define DFSDM_SEL(val) STM32_CLOCK(val, 1, 2, CCIPR2_REG) +#define ADFSDM_SEL(val) STM32_CLOCK(val, 3, 3, CCIPR2_REG) +/* #define SAI1_SEL(val) STM32_CLOCK(val, 7, 5, CCIPR2_REG) */ +/* #define SAI2_SEL(val) STM32_CLOCK(val, 7, 8, CCIPR2_REG) */ +#define DSI_SEL(val) STM32_CLOCK(val, 1, 12, CCIPR2_REG) +#define SDMMC_SEL(val) STM32_CLOCK(val, 1, 14, CCIPR2_REG) +#define OSPI_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR2_REG) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L4_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32u5_clock.h b/include/zephyr/dt-bindings/clock/stm32u5_clock.h index 4e02e83270252..b725a0e69bd4a 100644 --- a/include/zephyr/dt-bindings/clock/stm32u5_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32u5_clock.h @@ -8,6 +8,35 @@ /** Peripheral clock sources */ +/* RM0468, Table 56 Kernel clock distribution summary */ + +/** PLL outputs */ +#define STM32_SRC_PLL1_P 0x001 +#define STM32_SRC_PLL1_Q 0x002 +#define STM32_SRC_PLL1_R 0x003 +/** PLL2/3 not yet supported */ +/* #define STM32_SRC_PLL2_P 0x004 */ +/* #define STM32_SRC_PLL2_Q 0x005 */ +/* #define STM32_SRC_PLL2_R 0x006 */ +/* #define STM32_SRC_PLL3_P 0x007 */ +/* #define STM32_SRC_PLL3_Q 0x008 */ +/* #define STM32_SRC_PLL3_R 0x009 */ +/** Fixed clocks */ +#define STM32_SRC_HSE 0x00A +#define STM32_SRC_LSE 0x00B +#define STM32_SRC_LSI 0x00C +#define STM32_SRC_HSI16 0x00D +/* #define STM32_SRC_HSI48 0x00E */ +#define STM32_SRC_MSIS 0x00F +#define STM32_SRC_MSIK 0x010 +/** Core clock */ +#define STM32_SRC_SYSCLK 0x011 +/** Clock muxes */ +/* #define STM32_SRC_ICLK 0x012 */ + +#define STM32_SRC_CLOCK_MIN STM32_SRC_PLL1_P +#define STM32_SRC_CLOCK_MAX STM32_SRC_SYSCLK + /** Bus clocks */ #define STM32_CLOCK_BUS_AHB1 0x088 #define STM32_CLOCK_BUS_AHB2 0x08C @@ -21,4 +50,73 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB3 +/** + * @brief STM32U5 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CCIPRx register offset (RM0456.pdf) */ +#define CCIPR1_REG 0xE0 +#define CCIPR2_REG 0xE4 +#define CCIPR3_REG 0xE8 + +/** @brief Device clk sources selection helpers */ +/** CCIPR1 devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR1_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR1_REG) +#define USART3_SEL(val) STM32_CLOCK(val, 3, 4, CCIPR1_REG) +#define USART4_SEL(val) STM32_CLOCK(val, 3, 6, CCIPR1_REG) +#define USART5_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR1_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR1_REG) +#define I2C2_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR1_REG) +#define I2C4_SEL(val) STM32_CLOCK(val, 3, 14, CCIPR1_REG) +#define SPI2_SEL(val) STM32_CLOCK(val, 3, 16, CCIPR1_REG) +#define LPTIM2_SEL(val) STM32_CLOCK(val, 3, 18, CCIPR1_REG) +#define SPI1_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR1_REG) +#define SYSTICK_SEL(val) STM32_CLOCK(val, 3, 22, CCIPR1_REG) +#define FDCAN1_SEL(val) STM32_CLOCK(val, 3, 24, CCIPR1_REG) +#define ICKLK_SEL(val) STM32_CLOCK(val, 3, 26, CCIPR1_REG) +#define TIMIC_SEL(val) STM32_CLOCK(val, 7, 29, CCIPR1_REG) +/** CCIPR2 devices */ +#define MDF1_SEL(val) STM32_CLOCK(val, 7, 0, CCIPR2_REG) +#define SAI1_SEL(val) STM32_CLOCK(val, 7, 5, CCIPR2_REG) +#define SAI2_SEL(val) STM32_CLOCK(val, 7, 8, CCIPR2_REG) +#define SAE_SEL(val) STM32_CLOCK(val, 1, 11, CCIPR2_REG) +#define RNG_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR2_REG) +#define SDMMC_SEL(val) STM32_CLOCK(val, 1, 14, CCIPR2_REG) +#define OCTOSPI_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR2_REG) +/** CCIPR3 devices */ +#define LPUART1_SEL(val) STM32_CLOCK(val, 7, 0, CCIPR3_REG) +#define SPI3_SEL(val) STM32_CLOCK(val, 3, 3, CCIPR3_REG) +#define I2C3_SEL(val) STM32_CLOCK(val, 3, 6, CCIPR3_REG) +#define LPTIM34_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR3_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR3_REG) +#define ADCDAC_SEL(val) STM32_CLOCK(val, 7, 12, CCIPR3_REG) +#define DAC1_SEL(val) STM32_CLOCK(val, 1, 15, CCIPR3_REG) +#define ADF1_SEL(val) STM32_CLOCK(val, 7, 16, CCIPR3_REG) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32U5_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32wb_clock.h b/include/zephyr/dt-bindings/clock/stm32wb_clock.h new file mode 100644 index 0000000000000..ec3a3f2f68127 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/stm32wb_clock.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WB_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WB_CLOCK_H_ + +/** Bus clocks */ +#define STM32_CLOCK_BUS_AHB1 0x048 +#define STM32_CLOCK_BUS_AHB2 0x04c +#define STM32_CLOCK_BUS_AHB3 0x050 +#define STM32_CLOCK_BUS_APB1 0x058 +#define STM32_CLOCK_BUS_APB1_2 0x05c +#define STM32_CLOCK_BUS_APB2 0x060 + +#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 +#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB2 + +/** Peripheral clock sources */ +/* RM0434, § Clock configuration register (RCC_CCIPRx) */ + +/** Fixed clocks */ +#define STM32_SRC_HSI 0x001 +/* #define STM32_SRC_HSI48 0x002 */ +#define STM32_SRC_LSE 0x003 +#define STM32_SRC_LSI 0x004 +#define STM32_SRC_MSI 0x005 +/** System clock */ +#define STM32_SRC_SYSCLK 0x006 +/** Bus clock */ +#define STM32_SRC_PCLK 0x007 +/** PLL clocks */ +#define STM32_SRC_PLLCLK 0x008 +/* TODO: PLLSAI clocks */ + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSI +#define STM32_SRC_CLOCK_MAX STM32_SRC_PLLCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CCIPR register offset */ +#define CCIPR_REG 0x88 + +/** @brief Device clk sources selection helpers */ +/** CCIPR devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR_REG) +#define LPUART1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR_REG) +#define I2C3_SEL(val) STM32_CLOCK(val, 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR_REG) +#define SAI1_SEL(val) STM32_CLOCK(val, 3, 22, CCIPR_REG) +#define CLK48_SEL(val) STM32_CLOCK(val, 3, 26, CCIPR_REG) +#define ADC_SEL(val) STM32_CLOCK(val, 3, 28, CCIPR_REG) +#define RNG_SEL(val) STM32_CLOCK(val, 3, 30, CCIPR_REG) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WB_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32wl_clock.h b/include/zephyr/dt-bindings/clock/stm32wl_clock.h index 3c2a7b581d9d8..202da3e8172f4 100644 --- a/include/zephyr/dt-bindings/clock/stm32wl_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32wl_clock.h @@ -6,8 +6,6 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WL_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WL_CLOCK_H_ -/** Peripheral clock sources */ - /** Bus clocks */ #define STM32_CLOCK_BUS_AHB1 0x048 #define STM32_CLOCK_BUS_AHB2 0x04c @@ -20,4 +18,69 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB3 +/** Peripheral clock sources */ +/* RM0461, §6.4.29 Clock configuration register (RCC_CFGR3) */ + +/** Fixed clocks */ +#define STM32_SRC_HSI 0x001 +#define STM32_SRC_LSE 0x002 +#define STM32_SRC_LSI 0x003 +/* #define STM32_SRC_HSI48 0x004 */ +/** System clock */ +#define STM32_SRC_SYSCLK 0x005 +/** Bus clock */ +#define STM32_SRC_PCLK 0x006 +/** PLL clock */ +#define STM32_SRC_PLLCLK 0x007 + +#define STM32_SRC_CLOCK_MIN STM32_SRC_HSI +#define STM32_SRC_CLOCK_MAX STM32_SRC_PLLCLK + +/** + * @brief STM32 clock configuration bit field. + * + * - reg (1/2/3) [ 0 : 7 ] + * - shift (0..31) [ 8 : 12 ] + * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] + * - val (0..7) [ 16 : 18 ] + * + * @param reg RCC_CCIPRx register offset + * @param shift Position within RCC_CCIPRx. + * @param mask Mask for the RCC_CCIPRx field. + * @param val Clock value (0, 1, ... 7). + */ + +#define STM32_CLOCK_REG_MASK 0xFFU +#define STM32_CLOCK_REG_SHIFT 0U +#define STM32_CLOCK_SHIFT_MASK 0x1FU +#define STM32_CLOCK_SHIFT_SHIFT 8U +#define STM32_CLOCK_MASK_MASK 0x7U +#define STM32_CLOCK_MASK_SHIFT 13U +#define STM32_CLOCK_VAL_MASK 0x7U +#define STM32_CLOCK_VAL_SHIFT 16U + +#define STM32_CLOCK(val, mask, shift, reg) \ + ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ + (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ + (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ + (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) + +/** @brief RCC_CCIPR register offset */ +#define CCIPR_REG 0x88 + +/** @brief Device clk sources selection helpers */ +/** CCIPR devices */ +#define USART1_SEL(val) STM32_CLOCK(val, 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_CLOCK(val, 3, 2, CCIPR_REG) +#define SPI2_SEL(val) STM32_CLOCK(val, 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_CLOCK(val, 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_CLOCK(val, 3, 12, CCIPR_REG) +#define I2C2_SEL(val) STM32_CLOCK(val, 3, 14, CCIPR_REG) +#define I2C3_SEL(val) STM32_CLOCK(val, 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_CLOCK(val, 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_CLOCK(val, 3, 20, CCIPR_REG) +#define LPTIM3_SEL(val) STM32_CLOCK(val, 3, 22, CCIPR_REG) +#define ADC_SEL(val) STM32_CLOCK(val, 3, 28, CCIPR_REG) +#define RNG_SEL(val) STM32_CLOCK(val, 3, 30, CCIPR_REG) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WL_CLOCK_H_ */ diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/CMakeLists.txt b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/CMakeLists.txt new file mode 100644 index 0000000000000..292ba0ea872aa --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(stm32_clock_configuration_common_core) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_clocks.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_clocks.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_clocks.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_clocks.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_f0_f1_f3_clocks.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_f0_f1_f3_clocks.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_f0_f1_f3_clocks.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_f0_f1_f3_clocks.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_f2_f4_f7_clocks.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_f2_f4_f7_clocks.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_f2_f4_f7_clocks.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_f2_f4_f7_clocks.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_msi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_msi.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/clear_msi.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/clear_msi.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f0_f3_pll_32_hse_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f0_f3_pll_32_hse_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f0_f3_pll_32_hse_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f0_f3_pll_32_hse_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f0_f3_pll_32_hsi_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f0_f3_pll_32_hsi_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f0_f3_pll_32_hsi_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f0_f3_pll_32_hsi_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f1_pll_64_hse_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f1_pll_64_hse_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f1_pll_64_hse_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f1_pll_64_hse_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f1_pll_64_hsi_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f1_pll_64_hsi_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f1_pll_64_hsi_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f1_pll_64_hsi_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f2_f4_f7_pll_100_hsi_16_ahb_2.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f2_f4_f7_pll_100_hsi_16_ahb_2.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f2_f4_f7_pll_100_hsi_16_ahb_2.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f2_f4_f7_pll_100_hsi_16_ahb_2.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f2_f4_f7_pll_64_hse_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f2_f4_f7_pll_64_hse_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f2_f4_f7_pll_64_hse_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f2_f4_f7_pll_64_hse_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f2_f4_f7_pll_64_hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f2_f4_f7_pll_64_hsi_16.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/f2_f4_f7_pll_64_hsi_16.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/f2_f4_f7_pll_64_hsi_16.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_24.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_24.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_24.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_24.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_32.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_32.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_32.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_32.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_8_bypass.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_8_bypass.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hse_8_bypass.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hse_8_bypass.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hsi_16.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hsi_16.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hsi_16.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hsi_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hsi_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/hsi_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/hsi_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/msi_range11.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/msi_range11.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/msi_range11.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/msi_range11.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/msi_range6.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/msi_range6.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/msi_range6.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/msi_range6.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_170_hse_24.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_170_hse_24.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_170_hse_24.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_170_hse_24.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_32_hse_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_32_hse_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_32_hse_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_32_hse_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_32_hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_32_hsi_16.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_32_hsi_16.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_32_hsi_16.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_48_hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_48_hsi_16.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_48_hsi_16.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_48_hsi_16.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_48_msi_4.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_48_msi_4.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_48_msi_4.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_48_msi_4.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_64_hse_8.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_64_hse_8.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_64_hse_8.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_64_hse_8.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_64_hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_64_hsi_16.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/pll_64_hsi_16.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/pll_64_hsi_16.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wb_pll_48_hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wb_pll_48_hsi_16.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wb_pll_48_hsi_16.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wb_pll_48_hsi_16.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wb_pll_48_msi_4.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wb_pll_48_msi_4.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wb_pll_48_msi_4.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wb_pll_48_msi_4.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wb_pll_64_hse_32.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wb_pll_64_hse_32.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wb_pll_64_hse_32.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wb_pll_64_hse_32.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wl_32_hse.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wl_32_hse.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wl_32_hse.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wl_32_hse.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wl_pll_48_hse_32.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wl_pll_48_hse_32.overlay similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/boards/wl_pll_48_hse_32.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/boards/wl_pll_48_hse_32.overlay diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/prj.conf similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/prj.conf rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/prj.conf diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/src/test_stm32_clock_configuration.c b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/src/test_stm32_clock_configuration.c similarity index 100% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/src/test_stm32_clock_configuration.c rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/src/test_stm32_clock_configuration.c diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml similarity index 69% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/testcase.yaml rename to tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml index 6d48812708ad7..1121f745febf5 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_core/testcase.yaml @@ -7,114 +7,114 @@ common: timeout: 5 tests: - drivers.stm32_clock_configuration.common.l4_l5.sysclksrc_pll_48_msi_4: + drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_48_msi_4: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/pll_48_msi_4.overlay" platform_allow: disco_l475_iot1 nucleo_l4r5zi stm32l562e_dk - drivers.stm32_clock_configuration.common.l4_l5.sysclksrc_pll_64_hsi_16: + drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_64_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/pll_64_hsi_16.overlay" platform_allow: disco_l475_iot1 nucleo_l4r5zi stm32l562e_dk - drivers.stm32_clock_configuration.common.sysclksrc_hsi_16: + drivers.stm32_clock_configuration.common_core.sysclksrc_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/hsi_16.overlay" platform_allow: disco_l475_iot1 nucleo_l4r5zi stm32l562e_dk nucleo_wb55rg nucleo_wl55jc - drivers.stm32_clock_configuration.common.sysclksrc_msi_48: + drivers.stm32_clock_configuration.common_core.sysclksrc_msi_48: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/msi_range11.overlay" platform_allow: disco_l475_iot1 nucleo_l4r5zi stm32l562e_dk nucleo_wl55jc nucleo_wb55rg - drivers.stm32_clock_configuration.common.l4_l5.sysclksrc_hse_8.fixup: + drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_hse_8.fixup: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/hse_8.overlay" platform_allow: disco_l475_iot1 nucleo_l4r5zi stm32l562e_dk harness: ztest harness_config: fixture: mco_sb_closed - drivers.stm32_clock_configuration.common.l4_l5.sysclksrc_pll_64_hse_8.fixup: + drivers.stm32_clock_configuration.common_core.l4_l5.sysclksrc_pll_64_hse_8.fixup: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/pll_64_hse_8.overlay" platform_allow: disco_l475_iot1 nucleo_l4r5zi stm32l562e_dk harness: ztest harness_config: fixture: mco_sb_closed - drivers.stm32_clock_configuration.common.g0.sysclksrc_pll_64_hse_8: + drivers.stm32_clock_configuration.common_core.g0.sysclksrc_pll_64_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_64_hse_8.overlay" platform_allow: nucleo_g071rb harness: ztest harness_config: fixture: mco_sb_closed - drivers.stm32_clock_configuration.common.g0_g4.sysclksrc_pll_64_hsi_16: + drivers.stm32_clock_configuration.common_core.g0_g4.sysclksrc_pll_64_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_64_hsi_16.overlay" platform_allow: nucleo_g071rb nucleo_g474re - drivers.stm32_clock_configuration.common.g0_g4.sysclksrc_hsi_16: + drivers.stm32_clock_configuration.common_core.g0_g4.sysclksrc_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hsi_16.overlay" platform_allow: nucleo_g071rb nucleo_g474re - drivers.stm32_clock_configuration.common.g4.sysclksrc_hse_24: + drivers.stm32_clock_configuration.common_core.g4.sysclksrc_hse_24: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_24.overlay" platform_allow: nucleo_g474re - drivers.stm32_clock_configuration.common.l0_l1.sysclksrc_hse_8: + drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/clear_msi.overlay;boards/hse_8.overlay" platform_allow: nucleo_l152re nucleo_l073rz - drivers.stm32_clock_configuration.common.l0_l1.sysclksrc_pll_32_hse_8: + drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_pll_32_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_32_hse_8.overlay" platform_allow: nucleo_l152re nucleo_l073rz - drivers.stm32_clock_configuration.common.l0_l1.sysclksrc_pll_32_hsi_16: + drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_pll_32_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_32_hsi_16.overlay" platform_allow: nucleo_l152re nucleo_l073rz - drivers.stm32_clock_configuration.common.l0_l1.sysclksrc_msi_range6: + drivers.stm32_clock_configuration.common_core.l0_l1.sysclksrc_msi_range6: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/msi_range6.overlay" platform_allow: nucleo_l152re nucleo_l073rz - drivers.stm32_clock_configuration.common.wl.sysclksrc_pll_48_hsi_16: + drivers.stm32_clock_configuration.common_core.wl.sysclksrc_pll_48_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_48_hsi_16.overlay" platform_allow: nucleo_wl55jc - drivers.stm32_clock_configuration.common.wl.sysclksrc_pll_48_hse_32: + drivers.stm32_clock_configuration.common_core.wl.sysclksrc_pll_48_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wl_pll_48_hse_32.overlay" platform_allow: nucleo_wl55jc - drivers.stm32_clock_configuration.common.wl.sysclksrc_hse_32: + drivers.stm32_clock_configuration.common_core.wl.sysclksrc_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wl_32_hse.overlay" platform_allow: nucleo_wl55jc - drivers.stm32_clock_configuration.common.wb.sysclksrc_hse_32: + drivers.stm32_clock_configuration.common_core.wb.sysclksrc_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/hse_32.overlay" platform_allow: nucleo_wb55rg - drivers.stm32_clock_configuration.common.wb.sysclksrc_pll_48_hsi_16: + drivers.stm32_clock_configuration.common_core.wb.sysclksrc_pll_48_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wb_pll_48_hsi_16.overlay" platform_allow: nucleo_wb55rg - drivers.stm32_clock_configuration.common.wb.sysclksrc_pll_64_hse_32: + drivers.stm32_clock_configuration.common_core.wb.sysclksrc_pll_64_hse_32: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wb_pll_64_hse_32.overlay" platform_allow: nucleo_wb55rg - drivers.stm32_clock_configuration.common.wb.sysclksrc_pll_48_msi_4: + drivers.stm32_clock_configuration.common_core.wb.sysclksrc_pll_48_msi_4: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/wb_pll_48_msi_4.overlay" platform_allow: nucleo_wb55rg - drivers.stm32_clock_configuration.common.f0_f3.sysclksrc_hsi_8: + drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hsi_8.overlay" platform_allow: nucleo_f091rc stm32f3_disco - drivers.stm32_clock_configuration.common.f0_f3.sysclksrc_hse_8: + drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hse_8_bypass.overlay" platform_allow: nucleo_f091rc stm32f3_disco - drivers.stm32_clock_configuration.common.f0_f3.sysclksrc_pll_32_hsi_8: + drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_pll_32_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f0_f3_pll_32_hsi_8.overlay" platform_allow: nucleo_f091rc stm32f3_disco - drivers.stm32_clock_configuration.common.f0_f3.sysclksrc_pll_32_hse_8: + drivers.stm32_clock_configuration.common_core.f0_f3.sysclksrc_pll_32_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f0_f3_pll_32_hse_8.overlay" platform_allow: nucleo_f091rc stm32f3_disco - drivers.stm32_clock_configuration.common.f1.sysclksrc_hsi_8: + drivers.stm32_clock_configuration.common_core.f1.sysclksrc_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hsi_8.overlay" platform_allow: nucleo_f103rb - drivers.stm32_clock_configuration.common.f1.sysclksrc_hse_8: + drivers.stm32_clock_configuration.common_core.f1.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/hse_8.overlay" platform_allow: nucleo_f103rb - drivers.stm32_clock_configuration.common.f1.sysclksrc_pll_64_hsi_8: + drivers.stm32_clock_configuration.common_core.f1.sysclksrc_pll_64_hsi_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f1_pll_64_hsi_8.overlay" platform_allow: nucleo_f103rb - drivers.stm32_clock_configuration.common.f1.sysclksrc_pll_64_hse_8: + drivers.stm32_clock_configuration.common_core.f1.sysclksrc_pll_64_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f0_f1_f3_clocks.overlay;boards/f1_pll_64_hse_8.overlay" platform_allow: nucleo_f103rb - drivers.stm32_clock_configuration.common.f2_f4_f7.sysclksrc_hsi_16: + drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/hsi_16.overlay" platform_allow: nucleo_f207zg nucleo_f429zi nucleo_f446re nucleo_f746zg - drivers.stm32_clock_configuration.common.f2_f4_f7.sysclksrc_hse_8: + drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/hse_8.overlay" platform_allow: nucleo_f207zg nucleo_f429zi nucleo_f446re nucleo_f746zg - drivers.stm32_clock_configuration.common.f2_f4_f7.sysclksrc_pll_64_hsi_16: + drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_64_hsi_16: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/f2_f4_f7_pll_64_hsi_16.overlay" platform_allow: nucleo_f207zg nucleo_f429zi nucleo_f446re nucleo_f746zg - drivers.stm32_clock_configuration.common.f2_f4_f7.sysclksrc_pll_64_hse_8: + drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_64_hse_8: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/f2_f4_f7_pll_64_hse_8.overlay" platform_allow: nucleo_f207zg nucleo_f429zi nucleo_f446re nucleo_f746zg - drivers.stm32_clock_configuration.common.f2_f4_f7.sysclksrc_pll_100_hsi_16_ahb2: + drivers.stm32_clock_configuration.common_core.f2_f4_f7.sysclksrc_pll_100_hsi_16_ahb2: extra_args: DTC_OVERLAY_FILE="boards/clear_f2_f4_f7_clocks.overlay;boards/f2_f4_f7_pll_100_hsi_16_ahb_2.overlay" platform_allow: nucleo_f207zg nucleo_f429zi nucleo_f446re nucleo_f746zg diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/CMakeLists.txt b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/CMakeLists.txt new file mode 100644 index 0000000000000..b8673d01dcd9b --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(stm32_clock_configuration_common_devices) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f0_i2c1_hsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f0_i2c1_hsi.overlay new file mode 100644 index 0000000000000..b455df2defdc8 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f0_i2c1_hsi.overlay @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; +}; + +&clk_lse { + status = "disabled"; +}; + +&clk_lsi { + status = "disabled"; +}; + +&pll { + /delete-property/ mul; + /delete-property/ div; + /delete-property/ prediv; + /delete-property/ xtpre; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hsi { + clock-frequency = ; + status = "okay"; +}; + +&pll { + prediv = <2>; + mul = <8>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f3_i2c1_hsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f3_i2c1_hsi.overlay new file mode 100644 index 0000000000000..f9c564c48574a --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f3_i2c1_hsi.overlay @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; +}; + +&clk_lse { + status = "disabled"; +}; + +&clk_lsi { + status = "disabled"; +}; + +&pll { + /delete-property/ mul; + /delete-property/ div; + /delete-property/ prediv; + /delete-property/ xtpre; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hsi { + clock-frequency = ; + status = "okay"; +}; + +&pll { + prediv = <2>; + mul = <8>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <2>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g0_i2c1_hsi_lptim1_lse.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g0_i2c1_hsi_lptim1_lse.overlay new file mode 100644 index 0000000000000..12322253761fe --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g0_i2c1_hsi_lptim1_lse.overlay @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hsi { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <8>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <2>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + status = "okay"; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g0_i2c1_sysclk_lptim1_lsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g0_i2c1_sysclk_lptim1_lsi.overlay new file mode 100644 index 0000000000000..30c2362b5835c --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g0_i2c1_sysclk_lptim1_lsi.overlay @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hsi { + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <8>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <2>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_SYSCLK I2C1_SEL(1)>; + status = "okay"; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g4_i2c1_hsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g4_i2c1_hsi.overlay new file mode 100644 index 0000000000000..eb31f732501c3 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/g4_i2c1_hsi.overlay @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hsi { + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <8>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <2>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/l4_i2c1_hsi_lptim1_lse.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/l4_i2c1_hsi_lptim1_lse.overlay new file mode 100644 index 0000000000000..e28815019f7c5 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/l4_i2c1_hsi_lptim1_lse.overlay @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; +}; + +&clk_msi { + status = "disabled"; + /delete-property/ msi-range; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hsi { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <20>; + div-p = <7>; + div-q = <2>; + div-r = <4>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + status = "okay"; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/l4_i2c1_sysclk_lptim1_lsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/l4_i2c1_sysclk_lptim1_lsi.overlay new file mode 100644 index 0000000000000..ecd08bc646fe2 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/l4_i2c1_sysclk_lptim1_lsi.overlay @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; +}; + +&clk_msi { + status = "disabled"; + /delete-property/ msi-range; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hsi { + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <20>; + div-p = <7>; + div-q = <2>; + div-r = <4>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_SYSCLK I2C1_SEL(1)>; + status = "okay"; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wb_i2c1_hsi_lptim1_lse.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wb_i2c1_hsi_lptim1_lse.overlay new file mode 100644 index 0000000000000..263fa70f89627 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wb_i2c1_hsi_lptim1_lse.overlay @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; + /delete-property/ hse-tcxo; + /delete-property/ hse-div2; +}; + +&clk_hsi { + status = "disabled"; + /delete-property/ hsi-div; +}; + +&clk_msi { + status = "disabled"; + /delete-property/ msi-range; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hse { + status = "okay"; + clock-frequency = ; +}; + +&clk_hsi { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&rcc { + clocks = <&clk_hse>; + clock-frequency = ; + cpu1-prescaler = <1>; + cpu2-prescaler = <1>; + ahb4-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + status = "okay"; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wb_i2c1_sysclk_lptim1_lsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wb_i2c1_sysclk_lptim1_lsi.overlay new file mode 100644 index 0000000000000..cf3d15c860775 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wb_i2c1_sysclk_lptim1_lsi.overlay @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; + /delete-property/ hse-tcxo; + /delete-property/ hse-div2; +}; + +&clk_hsi { + status = "disabled"; + /delete-property/ hsi-div; +}; + +&clk_msi { + status = "disabled"; + /delete-property/ msi-range; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hse { + status = "okay"; + clock-frequency = ; +}; + +&clk_lsi1 { + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&rcc { + clocks = <&clk_hse>; + clock-frequency = ; + cpu1-prescaler = <1>; + cpu2-prescaler = <1>; + ahb4-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_SYSCLK I2C1_SEL(1)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wl_i2c1_hsi_lptim1_lse.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wl_i2c1_hsi_lptim1_lse.overlay new file mode 100644 index 0000000000000..593408f4e4800 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wl_i2c1_hsi_lptim1_lse.overlay @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; + /delete-property/ hse-tcxo; + /delete-property/ hse-div2; +}; + +&clk_hsi { + status = "disabled"; + /delete-property/ hsi-div; +}; + +&clk_msi { + status = "disabled"; + /delete-property/ msi-range; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hse { + status = "okay"; + clock-frequency = ; +}; + +&clk_hsi { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&rcc { + clocks = <&clk_hse>; + clock-frequency = ; + cpu1-prescaler = <1>; + cpu2-prescaler = <1>; + ahb3-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_HSI I2C1_SEL(2)>; + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + pinctrl-names = "default"; + status = "okay"; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wl_i2c1_sysclk_lptim1_lsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wl_i2c1_sysclk_lptim1_lsi.overlay new file mode 100644 index 0000000000000..5868edffd3055 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/wl_i2c1_sysclk_lptim1_lsi.overlay @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; + /delete-property/ hse-tcxo; + /delete-property/ hse-div2; +}; + +&clk_hsi { + status = "disabled"; + /delete-property/ hsi-div; +}; + +&clk_msi { + status = "disabled"; + /delete-property/ msi-range; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; +}; + + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hse { + status = "okay"; + clock-frequency = ; +}; + +&clk_lsi { + status = "okay"; +}; + +&rcc { + clocks = <&clk_hse>; + clock-frequency = ; + cpu1-prescaler = <1>; + cpu2-prescaler = <1>; + ahb3-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&i2c1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00200000>, + <&rcc STM32_SRC_SYSCLK I2C1_SEL(1)>; + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + pinctrl-names = "default"; + status = "okay"; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/prj.conf new file mode 100644 index 0000000000000..9467c2926896d --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/src/test_stm32_clock_configuration.c b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/src/test_stm32_clock_configuration.c new file mode 100644 index 0000000000000..eb92741ad8de2 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/src/test_stm32_clock_configuration.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(test); + +#define DT_NO_CLOCK 0xFFFFU + +/* Not device related, but keep it to ensure core clock config is correct */ +static void test_sysclk_freq(void) +{ + uint32_t soc_sys_clk_freq; + + soc_sys_clk_freq = HAL_RCC_GetSysClockFreq(); + + zassert_equal(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, soc_sys_clk_freq, + "Expected sysclockfreq: %d. Actual sysclockfreq: %d", + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, soc_sys_clk_freq); +} + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_i2c_v1) +#define DT_DRV_COMPAT st_stm32_i2c_v1 +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_i2c_v2) +#define DT_DRV_COMPAT st_stm32_i2c_v2 +#endif + +#if STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT +#define STM32_I2C_OPT_CLOCK_SUPPORT 1 +#else +#define STM32_I2C_OPT_CLOCK_SUPPORT 0 +#endif + +static void test_i2c_clk_config(void) +{ + static const struct stm32_pclken pclken[] = STM32_DT_CLOCKS(i2c1); + + uint32_t dev_dt_clk_freq, dev_actual_clk_freq; + uint32_t dev_actual_clk_src; + int r; + + /* Test clock_on(gating clock) */ + r = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0]); + zassert_true((r == 0), "Could not enable I2C gating clock"); + + zassert_true(__HAL_RCC_I2C1_IS_CLK_ENABLED(), "I2C1 gating clock should be on"); + TC_PRINT("I2C1 gating clock on\n"); + + if (IS_ENABLED(STM32_I2C_OPT_CLOCK_SUPPORT) && DT_NUM_CLOCKS(DT_NODELABEL(i2c1)) > 1) { + /* Test clock_on(ker_clk) */ + r = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[1], + NULL); + zassert_true((r == 0), "Could not enable I2C soure clock"); + TC_PRINT("I2C1 source clock configured\n"); + + /* Test clock source */ + dev_actual_clk_src = __HAL_RCC_GET_I2C1_SOURCE(); + + if (pclken[1].bus == STM32_SRC_HSI) { + zassert_equal(dev_actual_clk_src, RCC_I2C1CLKSOURCE_HSI, + "Expected I2C src: HSI (0x%lx). Actual I2C src: 0x%x", + RCC_I2C1CLKSOURCE_HSI, dev_actual_clk_src); + } else if (pclken[1].bus == STM32_SRC_SYSCLK) { + zassert_equal(dev_actual_clk_src, RCC_I2C1CLKSOURCE_SYSCLK, + "Expected I2C src: SYSCLK (0x%lx). Actual I2C src: 0x%x", + RCC_I2C1CLKSOURCE_SYSCLK, dev_actual_clk_src); + } else { + zassert_true(0, "Unexpected src clk (%d)", dev_actual_clk_src); + } + + /* Test get_rate(srce clk) */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[1], + &dev_dt_clk_freq); + zassert_true((r == 0), "Could not get I2C clk srce freq"); + + dev_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2C1); + zassert_equal(dev_dt_clk_freq, dev_actual_clk_freq, + "Expected freq: %d Hz. Actual clk: %d Hz", + dev_dt_clk_freq, dev_actual_clk_freq); + + TC_PRINT("I2C1 clock source rate: %d Hz\n", dev_dt_clk_freq); + } else { + zassert_true((DT_NUM_CLOCKS(DT_NODELABEL(i2c1)) == 1), "test config issue"); + /* No alt clock available, get rate from gating clock */ + + /* Test get_rate */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0], + &dev_dt_clk_freq); + zassert_true((r == 0), "Could not get I2C clk freq"); + + dev_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2C1); + zassert_equal(dev_dt_clk_freq, dev_actual_clk_freq, + "Expected freq: %d Hz. Actual freq: %d Hz", + dev_dt_clk_freq, dev_actual_clk_freq); + + TC_PRINT("I2C1 clock source rate: %d Hz\n", dev_dt_clk_freq); + } + + /* Test clock_off(gating clk) */ + r = clock_control_off(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0]); + zassert_true((r == 0), "Could not disable I2C gating clk"); + + zassert_true(!__HAL_RCC_I2C1_IS_CLK_ENABLED(), "I2C1 gating clk should be off"); + TC_PRINT("I2C1 gating clk off\n"); + + /* Test clock_off(srce) */ + /* Not supported today */ +} +#else +static void test_i2c_clk_config(void) {} +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(lptim1), okay) + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT st_stm32_lptim + +#if STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT +#define STM32_LPTIM_OPT_CLOCK_SUPPORT 1 +#else +#define STM32_LPTIM_OPT_CLOCK_SUPPORT 0 +#endif + +static void test_lptim_clk_config(void) +{ + static const struct stm32_pclken pclken[] = STM32_DT_CLOCKS(lptim1); + + uint32_t dev_dt_clk_freq, dev_actual_clk_freq; + uint32_t dev_actual_clk_src; + int r; + + /* Test clock_on(gating clock) */ + r = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0]); + zassert_true((r == 0), "Could not enable LPTIM gating clock"); + + zassert_true(__HAL_RCC_LPTIM1_IS_CLK_ENABLED(), "LPTIM1 gating clock should be on"); + TC_PRINT("LPTIM1 gating clock on\n"); + + if (IS_ENABLED(STM32_LPTIM_OPT_CLOCK_SUPPORT) && DT_NUM_CLOCKS(DT_NODELABEL(lptim1)) > 1) { + /* Test clock_on(ker_clk) */ + r = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[1], + NULL); + zassert_true((r == 0), "Could not enable LPTIM1 soure clock"); + TC_PRINT("LPTIM1 source clock configured\n"); + + /* Test clock source */ + dev_actual_clk_src = __HAL_RCC_GET_LPTIM1_SOURCE(); + + if (pclken[1].bus == STM32_SRC_LSE) { + zassert_equal(dev_actual_clk_src, RCC_LPTIM1CLKSOURCE_LSE, + "Expected LPTIM1 src: LSE (0x%lx). Actual LPTIM1 src: 0x%x", + RCC_LPTIM1CLKSOURCE_LSE, dev_actual_clk_src); + } else if (pclken[1].bus == STM32_SRC_LSI) { + zassert_equal(dev_actual_clk_src, RCC_LPTIM1CLKSOURCE_LSI, + "Expected LPTIM1 src: LSI (0x%lx). Actual LPTIM1 src: 0x%x", + RCC_LPTIM1CLKSOURCE_LSI, dev_actual_clk_src); + } else { + zassert_true(0, "Unexpected src clk (%d)", dev_actual_clk_src); + } + + /* Test get_rate(srce clk) */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[1], + &dev_dt_clk_freq); + zassert_true((r == 0), "Could not get LPTIM1 clk srce freq"); + + dev_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_LPTIM1); + zassert_equal(dev_dt_clk_freq, dev_actual_clk_freq, + "Expected DT freq: %d Hz. Actual freq: %d Hz", + dev_dt_clk_freq, dev_actual_clk_freq); + + TC_PRINT("LPTIM1 clock source rate: %d Hz\n", dev_dt_clk_freq); + } else { + zassert_true((DT_NUM_CLOCKS(DT_NODELABEL(lptim1)) == 1), "test config issue"); + /* No alt clock available, get rate from gating clock */ + + /* Test get_rate */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0], + &dev_dt_clk_freq); + zassert_true((r == 0), "Could not get LPTIM1 clk freq"); + + dev_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_LPTIM1); + zassert_equal(dev_dt_clk_freq, dev_actual_clk_freq, + "Expected DT freq: %d Hz. Actual freq: %d Hz", + dev_dt_clk_freq, dev_actual_clk_freq); + + TC_PRINT("LPTIM1 clock source rate: %d Hz\n", dev_dt_clk_freq); + } + + /* Test clock_off(reg_clk) */ + r = clock_control_off(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0]); + zassert_true((r == 0), "Could not disable LPTIM1 gating clk"); + + zassert_true(!__HAL_RCC_I2C1_IS_CLK_ENABLED(), "LPTIM1 gating clk should be off"); + TC_PRINT("LPTIM1 gating clk off\n"); + + /* Test clock_off(srce) */ + /* Not supported today */ +} +#else +static void test_lptim_clk_config(void) {} +#endif + +void test_main(void) +{ + ztest_test_suite(test_stm32_common_devices_clocks, + ztest_unit_test(test_sysclk_freq), + ztest_unit_test(test_i2c_clk_config), + ztest_unit_test(test_lptim_clk_config) + ); + ztest_run_test_suite(test_stm32_common_devices_clocks); +} diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/testcase.yaml new file mode 100644 index 0000000000000..5b302478671b7 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/testcase.yaml @@ -0,0 +1,36 @@ +common: + timeout: 5 +tests: + drivers.stm32_clock_configuration.common_device.wb.i2c1_hsi_lptim1_lse: + extra_args: DTC_OVERLAY_FILE="boards/wb_i2c1_hsi_lptim1_lse.overlay" + platform_allow: nucleo_wb55rg + drivers.stm32_clock_configuration.common_device.wb.i2c1_sysclk_lptim1_lsi: + extra_args: DTC_OVERLAY_FILE="boards/wb_i2c1_sysclk_lptim1_lsi.overlay" + platform_allow: nucleo_wb55rg + drivers.stm32_clock_configuration.common_device.g0.i2c1_sysclk_lptim1_lsi: + extra_args: DTC_OVERLAY_FILE="boards/g0_i2c1_sysclk_lptim1_lsi.overlay" + platform_allow: nucleo_g071rb + drivers.stm32_clock_configuration.common_device.g0.i2c1_hsi_lptim1_lse: + extra_args: DTC_OVERLAY_FILE="boards/g0_i2c1_hsi_lptim1_lse.overlay" + platform_allow: nucleo_g071rb + drivers.stm32_clock_configuration.common_device.wl.i2c1_hsi_lptim1_lse: + extra_args: DTC_OVERLAY_FILE="boards/wl_i2c1_hsi_lptim1_lse.overlay" + platform_allow: nucleo_wl55jc + drivers.stm32_clock_configuration.common_device.wl.i2c1_sysclk_lptim1_lsi: + extra_args: DTC_OVERLAY_FILE="boards/wl_i2c1_sysclk_lptim1_lsi.overlay" + platform_allow: nucleo_wl55jc + drivers.stm32_clock_configuration.common_device.l4.i2c1_sysclk_lptim1_lsi: + extra_args: DTC_OVERLAY_FILE="boards/l4_i2c1_sysclk_lptim1_lsi.overlay" + platform_allow: disco_l475_iot1 + drivers.stm32_clock_configuration.common_device.l4.i2c1_hsi_lptim1_lse: + extra_args: DTC_OVERLAY_FILE="boards/l4_i2c1_hsi_lptim1_lse.overlay" + platform_allow: disco_l475_iot1 + drivers.stm32_clock_configuration.common_device.g4.i2c1_hsi: + extra_args: DTC_OVERLAY_FILE="boards/g4_i2c1_hsi.overlay" + platform_allow: nucleo_g474re + drivers.stm32_clock_configuration.common_device.f0.i2c1_hsi: + extra_args: DTC_OVERLAY_FILE="boards/f0_i2c1_hsi.overlay" + platform_allow: nucleo_f091rc + drivers.stm32_clock_configuration.common_device.f3.i2c1_hsi: + extra_args: DTC_OVERLAY_FILE="boards/f3_i2c1_hsi.overlay" + platform_allow: stm32f3_disco diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/CMakeLists.txt b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/CMakeLists.txt similarity index 81% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32_common/CMakeLists.txt rename to tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/CMakeLists.txt index 2695a8f335652..fdef1a9b79454 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common/CMakeLists.txt +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(stm32_clock_configuration_common) +project(stm32_clock_configuration_h7_devices) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/core_init.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/core_init.overlay new file mode 100644 index 0000000000000..5b1e3c19f3aa7 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/core_init.overlay @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay clears clocks back to a state equivalent to what could + * be found in stm32h7.dtsi + */ + + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ hse-bypass; + /delete-property/ clock-frequency; +}; + +&clk_hsi { + status = "disabled"; + /delete-property/ hsi-div; +}; + +&clk_csi { + status = "disabled"; +}; + +&clk_lse { + status = "disabled"; +}; + +&clk_lsi { + status = "disabled"; +}; + +&pll { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&pll3 { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-p; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; + /delete-property/ d1cpre; + /delete-property/ hpre; + /delete-property/ d1ppre; + /delete-property/ d2ppre1; + /delete-property/ d2ppre2; + /delete-property/ d3ppre; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pb5>; + pinctrl-names = "default"; + status = "disabled"; +}; + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_hse { + hse-bypass; + clock-frequency = ; /* STLink 8MHz clock */ + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <24>; + div-p = <2>; + div-q = <1>; + div-r = <1>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + d1cpre = <1>; + hpre = <1>; + d1ppre = <1>; + d2ppre1 = <1>; + d2ppre2 = <1>; + d3ppre = <1>; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_per_ck_d1ppre_1.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_per_ck_d1ppre_1.overlay new file mode 100644 index 0000000000000..51bbd59a72b16 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_per_ck_d1ppre_1.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&clk_hsi { + status = "okay"; + hsi-div = <1>; +}; + +&perck { + clocks = <&rcc STM32_SRC_HSI_KER CKPER_SEL(0)>; + status = "okay"; +}; + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_CKPER SPI123_SEL(4)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_per_ck_hsi.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_per_ck_hsi.overlay new file mode 100644 index 0000000000000..d86ce050ef30b --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_per_ck_hsi.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&clk_hsi { + status = "okay"; + hsi-div = <8>; /* HSI RC: 64MHz, hsi_clk = 8MHz */ +}; + +&perck { + clocks = <&rcc STM32_SRC_HSI_KER CKPER_SEL(0)>; + status = "okay"; +}; + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_CKPER SPI123_SEL(4)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pll3p_1_d1ppre_4.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pll3p_1_d1ppre_4.overlay new file mode 100644 index 0000000000000..1244bf46db180 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pll3p_1_d1ppre_4.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&pll3 { + clocks = <&clk_hse>; + div-m = <1>; + mul-n = <24>; + div-p = <1>; + status = "okay"; +}; + +&rcc { + /delete-property/ d1ppre; + d1ppre = <4>; +}; + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_PLL3_P SPI123_SEL(2)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pllq_1_d1ppre_1.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pllq_1_d1ppre_1.overlay new file mode 100644 index 0000000000000..495e8c4b0012b --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pllq_1_d1ppre_1.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&pll { + /delete-property/ div-q; + div-q = <1>; +}; + +&rcc { + /delete-property/ d1ppre; + d1ppre = <1>; +}; + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_PLL1_Q SPI123_SEL(0)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pllq_2_d1ppre_4.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pllq_2_d1ppre_4.overlay new file mode 100644 index 0000000000000..9e4aff32b1686 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/boards/spi1_pllq_2_d1ppre_4.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +/* With this particular div-q and d1ppre values + * APB2 and PLL_Q clock frequencies are equal. + * This setting is default stm32h7 SPI devices configuration. + * This test config ensures it still works. + */ + +&pll { + /delete-property/ div-q; + div-q = <2>; +}; + +&rcc { + /delete-property/ d1ppre; + d1ppre = <4>; +}; + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/prj.conf new file mode 100644 index 0000000000000..9467c2926896d --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/src/test_stm32_clock_configuration.c b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/src/test_stm32_clock_configuration.c new file mode 100644 index 0000000000000..428d7f726fda8 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/src/test_stm32_clock_configuration.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(test); + +#define DT_DRV_COMPAT st_stm32_spi + +#if STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT +#define STM32_SPI_OPT_CLOCK_SUPPORT 1 +#else +#define STM32_SPI_OPT_CLOCK_SUPPORT 0 +#endif + +#define DT_NO_CLOCK 0xFFFFU + +/* Not device related, but keep it to ensure core clock config is correct */ +static void test_sysclk_freq(void) +{ + uint32_t soc_sys_clk_freq; + + soc_sys_clk_freq = HAL_RCC_GetSysClockFreq(); + + zassert_equal(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, soc_sys_clk_freq, + "Expected sysclockfreq: %d. Actual sysclockfreq: %d", + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, soc_sys_clk_freq); +} + +static void test_spi_clk_config(void) +{ + static const struct stm32_pclken pclken[] = STM32_DT_CLOCKS(spi1); + struct stm32_pclken spi1_reg_clk_cfg = pclken[0]; + + uint32_t spi1_actual_clk_src, spi1_dt_ker_clk_src; + uint32_t spi1_dt_clk_freq, spi1_actual_clk_freq; + int r; + + /* Test clock_on(reg_clk) */ + r = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &spi1_reg_clk_cfg); + zassert_true((r == 0), "Could not enable SPI reg_clk"); + + zassert_true(__HAL_RCC_SPI1_IS_CLK_ENABLED(), "SPI1 reg_clk should be on"); + TC_PRINT("SPI1 reg_clk on\n"); + + if (IS_ENABLED(STM32_SPI_OPT_CLOCK_SUPPORT) && DT_NUM_CLOCKS(DT_NODELABEL(spi1)) > 1) { + struct stm32_pclken spi1_ker_clk_cfg = pclken[1]; + + /* Select ker_clk as device source clock */ + r = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &spi1_ker_clk_cfg, + NULL); + zassert_true((r == 0), "Could not enable SPI ker_clk"); + TC_PRINT("SPI1 ker_clk on\n"); + + /* Test ker_clk is configured as device's source clock */ + spi1_dt_ker_clk_src = COND_CODE_1(DT_CLOCKS_HAS_NAME(DT_NODELABEL(spi1), kernel), + (DT_CLOCKS_CELL_BY_NAME(DT_NODELABEL(spi1), + kernel, bus)), + (DT_NO_CLOCK)); + spi1_actual_clk_src = __HAL_RCC_GET_SPI1_SOURCE(); + + if (spi1_dt_ker_clk_src == STM32_SRC_PLL1_Q) { + zassert_equal(spi1_actual_clk_src, RCC_SPI123CLKSOURCE_PLL, + "Expected SPI src: PLLQ (%d). Actual SPI src: %d", + spi1_actual_clk_src, RCC_SPI123CLKSOURCE_PLL); + } else if (spi1_dt_ker_clk_src == STM32_SRC_PLL3_P) { + zassert_equal(spi1_actual_clk_src, RCC_SPI123CLKSOURCE_PLL3, + "Expected SPI src: PLLQ (%d). Actual SPI src: %d", + spi1_actual_clk_src, RCC_SPI123CLKSOURCE_PLL3); + } else if (spi1_dt_ker_clk_src == STM32_SRC_CKPER) { + zassert_equal(spi1_actual_clk_src, RCC_SPI123CLKSOURCE_CLKP, + "Expected SPI src: PLLQ (%d). Actual SPI src: %d", + spi1_actual_clk_src, RCC_SPI123CLKSOURCE_CLKP); + } else { + zassert_true(1, "Unexpected ker_clk src(%d)", spi1_dt_ker_clk_src); + } + + /* Test get_rate(ker_clk) */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &spi1_ker_clk_cfg, + &spi1_dt_clk_freq); + zassert_true((r == 0), "Could not get SPI clk freq"); + + spi1_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI1); + zassert_equal(spi1_dt_clk_freq, spi1_actual_clk_freq, + "Expected SPI clk: (%d). Actual SPI clk: %d", + spi1_dt_clk_freq, spi1_actual_clk_freq); + } else { + /* No alt clock available, get rate from reg_clk */ + + /* Test get_rate(reg_clk) */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &spi1_reg_clk_cfg, + &spi1_dt_clk_freq); + zassert_true((r == 0), "Could not get SPI clk freq"); + + spi1_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI1); + zassert_equal(spi1_dt_clk_freq, spi1_actual_clk_freq, + "Expected SPI clk: (%d). Actual SPI clk: %d", + spi1_dt_clk_freq, spi1_actual_clk_freq); + } + + TC_PRINT("SPI1 clock freq: %d(MHz)\n", spi1_actual_clk_freq / (1000*1000)); + + /* Test clock_off(reg_clk) */ + r = clock_control_off(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &spi1_reg_clk_cfg); + zassert_true((r == 0), "Could not disable SPI reg_clk"); + + zassert_true(!__HAL_RCC_SPI1_IS_CLK_ENABLED(), "SPI1 reg_clk should be off"); + TC_PRINT("SPI1 reg_clk off\n"); + + /* Test clock_off(ker_clk) */ + /* Not supported today */ +} + +void test_main(void) +{ + ztest_test_suite(test_stm32h7_devices_clocks, + ztest_unit_test(test_sysclk_freq), + ztest_unit_test(test_spi_clk_config) + ); + ztest_run_test_suite(test_stm32h7_devices_clocks); +} diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/testcase.yaml new file mode 100644 index 0000000000000..0742d727e52fb --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32h7_devices/testcase.yaml @@ -0,0 +1,14 @@ +common: + timeout: 5 + platform_allow: nucleo_h723zg +tests: + drivers.stm32_clock_configuration.h7_dev.spi1_pllq_1_d1ppre_1: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pllq_1_d1ppre_1.overlay" + drivers.stm32_clock_configuration.h7_dev.spi1_pllq_2_d1ppre_4: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pllq_2_d1ppre_4.overlay" + drivers.stm32_clock_configuration.h7_dev.spi1_pll3p_1_d1ppre_4: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pll3p_1_d1ppre_4.overlay" + drivers.stm32_clock_configuration.h7_dev.spi1_per_ck_d1ppre_1: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_per_ck_d1ppre_1.overlay" + drivers.stm32_clock_configuration.h7_dev.spi1_per_ck_hsi: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_per_ck_hsi.overlay" diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_msis_ahb_2_80.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_msis_ahb_2_40.overlay similarity index 87% rename from tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_msis_ahb_2_80.overlay rename to tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_msis_ahb_2_40.overlay index d9c41e27f6290..22748c9ee0900 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_msis_ahb_2_80.overlay +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/boards/pll_msis_ahb_2_40.overlay @@ -21,9 +21,9 @@ &pll1 { div-m = <1>; - mul-n = <40>; - div-q = <1>; - div-r = <1>; + mul-n = <80>; + div-q = <4>; + div-r = <4>; clocks = <&clk_msis>; status = "okay"; }; @@ -31,7 +31,7 @@ &rcc { clocks = <&pll1>; ahb-prescaler = <2>; /* Use AHB prescaler to reduce HCLK */ - clock-frequency = ; + clock-frequency = ; apb1-prescaler = <1>; apb2-prescaler = <1>; apb3-prescaler = <1>; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml index 5298b3416da16..be7a98cd59692 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_core/testcase.yaml @@ -4,8 +4,8 @@ common: tests: drivers.stm32_clock_configuration.u5.sysclksrc_pll_msis_160: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_msis_160.overlay" - drivers.stm32_clock_configuration.u5.pll_msis_hab_2_80: - extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_msis_ahb_2_80.overlay" + drivers.stm32_clock_configuration.u5.pll_msis_hab_2_40: + extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_msis_ahb_2_40.overlay" drivers.stm32_clock_configuration.u5.sysclksrc_pll_hsi_160: extra_args: DTC_OVERLAY_FILE="boards/clear_clocks.overlay;boards/pll_hsi_160.overlay" drivers.stm32_clock_configuration.u5.sysclksrc_pll_hsi_40: diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/CMakeLists.txt b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/CMakeLists.txt new file mode 100644 index 0000000000000..4067c45f0f221 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(stm32_clock_configuration_u5_devices) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/core_init.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/core_init.overlay new file mode 100644 index 0000000000000..f0f50c54d8c70 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/core_init.overlay @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay clears clocks back to a state equivalent to what could + * be found in stm32h7.dtsi + */ + + +/* Clocks clean up config + * Aim is to avoid conflict with specific default board configuration + */ + +&clk_hse { + status = "disabled"; + /delete-property/ clock-frequency; + /delete-property/ hse-bypass; +}; + +&clk_hsi { + status = "disabled"; +}; + +&clk_lse { + status = "disabled"; +}; + +&clk_msis { + status = "disabled"; + /delete-property/ msi-range; + /delete-property/ msi-pll-mode; +}; + +&clk_msik { + status = "disabled"; + /delete-property/ msi-range; + /delete-property/ msi-pll-mode; +}; + +&pll1 { + /delete-property/ div-m; + /delete-property/ mul-n; + /delete-property/ div-q; + /delete-property/ div-r; + /delete-property/ clocks; + status = "disabled"; +}; + +&rcc { + /delete-property/ clocks; + /delete-property/ clock-frequency; + /delete-property/ ahb-prescaler; + /delete-property/ apb1-prescaler; + /delete-property/ apb2-prescaler; + /delete-property/ apb3-prescaler; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pe12 &spi1_sck_pe13 + &spi1_miso_pe14 &spi1_mosi_pe15>; + pinctrl-names = "default"; + status = "disabled"; +}; + +/* Core set up + * Aim of this part is to provide a base working clock config + */ + +&clk_lse { + status = "okay"; +}; + +&clk_msis { + status = "okay"; + msi-range = <4>; + msi-pll-mode; +}; + +&pll1 { + div-m = <1>; + mul-n = <80>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_msis>; + status = "okay"; +}; + +&rcc { + clocks = <&pll1>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb3-prescaler = <1>; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_hsi_16.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_hsi_16.overlay new file mode 100644 index 0000000000000..dd2f8fb132e46 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_hsi_16.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&clk_hsi { + status = "okay"; +}; + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_HSI16 SPI1_SEL(2)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_msik.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_msik.overlay new file mode 100644 index 0000000000000..dd398ab2e8ae8 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_msik.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&clk_msik { + msi-range = <4>; + status = "okay"; +}; + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_MSIK SPI1_SEL(3)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_pclk2.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_pclk2.overlay new file mode 100644 index 0000000000000..25f3558f26848 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_pclk2.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_sysclk.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_sysclk.overlay new file mode 100644 index 0000000000000..96bb9b308d5ae --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/boards/spi1_sysclk.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Warning: This overlay performs configuration from clean sheet. + * It is assumed that it is applied after core_init.overlay file. + */ + +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_SYSCLK SPI1_SEL(1)>; + status = "okay"; +}; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/prj.conf b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/prj.conf new file mode 100644 index 0000000000000..9467c2926896d --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/src/test_stm32_clock_configuration.c b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/src/test_stm32_clock_configuration.c new file mode 100644 index 0000000000000..f709d4845c0a1 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/src/test_stm32_clock_configuration.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(test); + +#define DT_DRV_COMPAT st_stm32_spi + +#if STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT +#define STM32_SPI_OPT_CLOCK_SUPPORT 1 +#else +#define STM32_SPI_OPT_CLOCK_SUPPORT 0 +#endif + +#define DT_NO_CLOCK 0xFFFFU + +/* Not device related, but keep it to ensure core clock config is correct */ +static void test_sysclk_freq(void) +{ + uint32_t soc_sys_clk_freq; + + soc_sys_clk_freq = HAL_RCC_GetSysClockFreq(); + + zassert_equal(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, soc_sys_clk_freq, + "Expected sysclockfreq: %d. Actual sysclockfreq: %d", + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, soc_sys_clk_freq); +} + +static void test_spi_clk_config(void) +{ + static const struct stm32_pclken pclken[] = STM32_DT_CLOCKS(spi1); + + uint32_t spi1_actual_clk_src; + uint32_t spi1_dt_clk_freq, spi1_actual_clk_freq; + int r; + + /* Test clock_on(reg_clk) */ + r = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0]); + zassert_true((r == 0), "Could not enable SPI gating clock"); + + zassert_true(__HAL_RCC_SPI1_IS_CLK_ENABLED(), "SPI1 gating clock should be on"); + TC_PRINT("SPI1 gating clock on\n"); + + if (IS_ENABLED(STM32_SPI_OPT_CLOCK_SUPPORT) && DT_NUM_CLOCKS(DT_NODELABEL(spi1)) > 1) { + /* Test clock_on(alt source) */ + r = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[1], + NULL); + zassert_true((r == 0), "Could not configure SPI source clk"); + TC_PRINT("SPI1 clk source configured\n"); + + /* Test clk source */ + spi1_actual_clk_src = __HAL_RCC_GET_SPI1_SOURCE(); + + if (pclken[1].bus == STM32_SRC_HSI16) { + zassert_equal(spi1_actual_clk_src, RCC_SPI1CLKSOURCE_HSI, + "Expected SPI src: HSI (%d). Actual SPI src: %d", + RCC_SPI1CLKSOURCE_HSI, spi1_actual_clk_src); + } else if (pclken[1].bus == STM32_SRC_SYSCLK) { + zassert_equal(spi1_actual_clk_src, RCC_SPI1CLKSOURCE_SYSCLK, + "Expected SPI src: SYSCLK (%d). Actual SPI src: %d", + RCC_SPI1CLKSOURCE_SYSCLK, spi1_actual_clk_src); + } else { + zassert_true(1, "Unexpected clk src(%d)", spi1_actual_clk_src); + } + + /* Test get_rate(source clk) */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[1], + &spi1_dt_clk_freq); + zassert_true((r == 0), "Could not get SPI clk freq"); + + spi1_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI1); + zassert_equal(spi1_dt_clk_freq, spi1_actual_clk_freq, + "Expected SPI clk: (%d). Actual SPI clk: %d", + spi1_dt_clk_freq, spi1_actual_clk_freq); + } else { + /* No alt clock available, get rate from gating clock */ + + /* Test get_rate(gating clock) */ + r = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0], + &spi1_dt_clk_freq); + zassert_true((r == 0), "Could not get SPI pclk freq"); + + spi1_actual_clk_freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI1); + zassert_equal(spi1_dt_clk_freq, spi1_actual_clk_freq, + "Expected SPI clk: (%d). Actual SPI clk: %d", + spi1_dt_clk_freq, spi1_actual_clk_freq); + } + + /* Test clock_off(gating clock) */ + r = clock_control_off(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &pclken[0]); + zassert_true((r == 0), "Could not disable SPI reg_clk"); + + zassert_true(!__HAL_RCC_SPI1_IS_CLK_ENABLED(), "SPI1 gating clock should be off"); + TC_PRINT("SPI1 gating clock off\n"); + + /* Test clock_off(source clk) */ + /* Not supported today */ +} + +void test_main(void) +{ + ztest_test_suite(test_stm32u5_devices_clocks, + ztest_unit_test(test_sysclk_freq), + ztest_unit_test(test_spi_clk_config) + ); + ztest_run_test_suite(test_stm32u5_devices_clocks); +} diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/testcase.yaml b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/testcase.yaml new file mode 100644 index 0000000000000..48148b8a89ca3 --- /dev/null +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32u5_devices/testcase.yaml @@ -0,0 +1,12 @@ +common: + timeout: 5 + platform_allow: b_u585i_iot02a +tests: + drivers.stm32_clock_configuration.dev_u5.spi1_pclk2: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_pclk2.overlay" + drivers.stm32_clock_configuration.dev_u5.spi1_hsi_16: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_hsi_16.overlay" + drivers.stm32_clock_configuration.dev_u5.spi1_msik: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_msik.overlay" + drivers.stm32_clock_configuration.dev_u5.spi1_sysclk: + extra_args: DTC_OVERLAY_FILE="boards/core_init.overlay;boards/spi1_sysclk.overlay" diff --git a/tests/drivers/spi/spi_loopback/boards/nucleo_h723zg.overlay b/tests/drivers/spi/spi_loopback/boards/nucleo_h723zg.overlay new file mode 100644 index 0000000000000..c9f83ed7e9b7d --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/nucleo_h723zg.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Set div-q to get test clk freq into acceptable SPI freq range */ +&pll { + /delete-property/ div-q; + div-q = <8>; +}; + +/* Define PLL1_Q as SPI1 kernel clock source */ +&spi1 { + /delete-property/ clocks; + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>, + <&rcc STM32_SRC_PLL1_Q SPI123_SEL(0)>; +};