From a5cc6c2e16b87f01d46a74ef25e80bda4a9620bf Mon Sep 17 00:00:00 2001 From: Thomas Stranger Date: Wed, 13 Jul 2022 10:38:03 +0200 Subject: [PATCH] drivers/can: stm32_fd: convert domain clk src sel. from kconfig to dts Use domain clocks if they are defined in dts. Until now domain clock sources could be selected via kconfig. STM32 platform now can configure domain clock sources via clock control driver, therefore this commit makes use of it. The configuration is shared between canfd instances, so a domain clock has to be defined for only one instance. Otherwise, only the configuration from the latest initialized instance will remain. The dependency on clock source PCLK1 for CAN_STM32FD_CLOCK_DIVISOR was removed, because the divider also divides other clocks. Note that setting that divider does not work at all at the moment, because the write protection is not disabled. Signed-off-by: Thomas Stranger --- drivers/can/Kconfig.stm32fd | 38 ------------------------- drivers/can/can_stm32fd.c | 55 +++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 68 deletions(-) diff --git a/drivers/can/Kconfig.stm32fd b/drivers/can/Kconfig.stm32fd index 74e483976a3..49d46e1d831 100644 --- a/drivers/can/Kconfig.stm32fd +++ b/drivers/can/Kconfig.stm32fd @@ -28,46 +28,8 @@ config CAN_MAX_EXT_ID_FILTER Defines the maximum number of filters with extended ID (29-bit) that can be attached. -choice CAN_STM32FD_CLOCK_SOURCE - prompt "CAN clock source" - default CAN_STM32FD_CLOCK_SOURCE_HSE - help - CAN clock source selection. - -config CAN_STM32FD_CLOCK_SOURCE_HSE - bool "HSE" - help - HSE clock used as FDCAN clock source. - -config CAN_STM32FD_CLOCK_SOURCE_PLL - bool "PLL" - depends on !SOC_SERIES_STM32U5X - help - PLL "Q" clock used ad FDCAN clock source. - -config CAN_STM32FD_CLOCK_SOURCE_PCLK1 - bool "PCLK1" - depends on !SOC_SERIES_STM32U5X - help - PCLK1 clock used ad FDCAN clock source. - -config CAN_STM32FD_CLOCK_SOURCE_PLL1Q - bool "PLL1Q" - depends on SOC_SERIES_STM32U5X - help - PLL1 "Q" clock used as FDCAN clock source. - -config CAN_STM32FD_CLOCK_SOURCE_PLL2P - bool "PLL2P" - depends on SOC_SERIES_STM32U5X - help - PLL2 "P" clock used as FDCAN clock source. - -endchoice - config CAN_STM32FD_CLOCK_DIVISOR int "CAN clock divisor" - depends on CAN_STM32FD_CLOCK_SOURCE_PCLK1 range 1 30 default 1 help diff --git a/drivers/can/can_stm32fd.c b/drivers/can/can_stm32fd.c index fedb785e146..ab4199d6b3e 100644 --- a/drivers/can/can_stm32fd.c +++ b/drivers/can/can_stm32fd.c @@ -12,27 +12,12 @@ #include #include #include -#include #include #include "can_mcan.h" LOG_MODULE_REGISTER(can_stm32fd, CONFIG_CAN_LOG_LEVEL); -#if defined(CONFIG_CAN_STM32FD_CLOCK_SOURCE_HSE) -#define CAN_STM32FD_CLOCK_SOURCE LL_RCC_FDCAN_CLKSOURCE_HSE -#elif defined(CONFIG_CAN_STM32FD_CLOCK_SOURCE_PLL) -#define CAN_STM32FD_CLOCK_SOURCE LL_RCC_FDCAN_CLKSOURCE_PLL -#elif defined(CONFIG_CAN_STM32FD_CLOCK_SOURCE_PCLK1) -#define CAN_STM32FD_CLOCK_SOURCE LL_RCC_FDCAN_CLKSOURCE_PCLK1 -#elif defined(CONFIG_CAN_STM32FD_CLOCK_SOURCE_PLL1Q) -#define CAN_STM32FD_CLOCK_SOURCE LL_RCC_FDCAN_CLKSOURCE_PLL1 -#elif defined(CONFIG_CAN_STM32FD_CLOCK_SOURCE_PLL2P) -#define CAN_STM32FD_CLOCK_SOURCE LL_RCC_FDCAN_CLKSOURCE_PLL2 -#else -#error "Unsupported FDCAN clock source" -#endif - #ifdef CONFIG_CAN_STM32FD_CLOCK_DIVISOR #if CONFIG_CAN_STM32FD_CLOCK_DIVISOR != 1 && CONFIG_CAN_STM32FD_CLOCK_DIVISOR & 0x01 #error CAN_STM32FD_CLOCK_DIVISOR invalid. Allowed values are 1 or 2 * n, where n <= 15. @@ -45,8 +30,17 @@ LOG_MODULE_REGISTER(can_stm32fd, CONFIG_CAN_LOG_LEVEL); #define DT_DRV_COMPAT st_stm32_fdcan +/* This symbol takes the value 1 if one of the device instances */ +/* is configured in dts with a domain clock */ +#if STM32_DT_INST_DEV_DOMAIN_CLOCK_SUPPORT +#define STM32_CANFD_DOMAIN_CLOCK_SUPPORT 1 +#else +#define STM32_CANFD_DOMAIN_CLOCK_SUPPORT 0 +#endif + struct can_stm32fd_config { - struct stm32_pclken pclken; + size_t pclk_len; + const struct stm32_pclken *pclken; void (*config_irq)(void); const struct pinctrl_dev_config *pcfg; }; @@ -74,20 +68,21 @@ static int can_stm32fd_clock_enable(const struct device *dev) const struct can_stm32fd_config *stm32fd_cfg = mcan_cfg->custom; const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); - LL_RCC_SetFDCANClockSource(CAN_STM32FD_CLOCK_SOURCE); - - /* LL_RCC API names do not align with PLL output name but are correct */ -#ifdef CONFIG_CAN_STM32FD_CLOCK_SOURCE_PLL1Q - LL_RCC_PLL1_EnableDomain_48M(); -#elif CONFIG_CAN_STM32FD_CLOCK_SOURCE_PLL2P - LL_RCC_PLL2_EnableDomain_SAI(); -#endif - if (!device_is_ready(clk)) { return -ENODEV; } - ret = clock_control_on(clk, (clock_control_subsys_t *)&stm32fd_cfg->pclken); + if (IS_ENABLED(STM32_CANFD_DOMAIN_CLOCK_SUPPORT) && (stm32fd_cfg->pclk_len > 1)) { + ret = clock_control_configure(clk, + (clock_control_subsys_t)&stm32fd_cfg->pclken[1], + NULL); + if (ret < 0) { + LOG_ERR("Could not select can_stm32fd domain clock"); + return ret; + } + } + + ret = clock_control_on(clk, (clock_control_subsys_t)&stm32fd_cfg->pclken[0]); if (ret < 0) { return ret; } @@ -190,12 +185,12 @@ static void config_can_##inst##_irq(void) \ #define CAN_STM32FD_CFG_INST(inst) \ PINCTRL_DT_INST_DEFINE(inst); \ + static const struct stm32_pclken can_stm32fd_pclken_##inst[] = \ + STM32_DT_INST_CLOCKS(inst); \ \ static const struct can_stm32fd_config can_stm32fd_cfg_##inst = { \ - .pclken = { \ - .enr = DT_INST_CLOCKS_CELL(inst, bits), \ - .bus = DT_INST_CLOCKS_CELL(inst, bus), \ - }, \ + .pclken = can_stm32fd_pclken_##inst, \ + .pclk_len = DT_INST_NUM_CLOCKS(inst), \ .config_irq = config_can_##inst##_irq, \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ }; \