From c91a70e130ea5c1591c126675dc19890eaa21384 Mon Sep 17 00:00:00 2001 From: Peter Maxwell Warasila Date: Thu, 28 Apr 2022 11:56:33 -0400 Subject: [PATCH] driver: can: stm32fd: add stm32u5 clock selection The STM32u% series of processors has a unique set of clock sources for the FDCAN peripheral. This brings the selection in line with the existing can_stm32fd clock selection Kconfigs. This change was tested on a proprietary board using the STM32U5 series which exposes the CAN pins of the SOC using a transciever on a live CAN bus as well as on the nucleo_g474re board from ST in loopback mode. HSE and PLL1Q tests run and all passed. PLL2P is not currently supported by the clock drivers for STM32U5, and as such is currently untested. When this support is added, the driver should be able to use this clock without issue. When changes from #42097 are merged this fix should be deprecated in favor of using the methods outlined there. Signed-off-by: Peter Maxwell Warasila --- drivers/can/Kconfig.stm32fd | 14 ++++++++++++++ drivers/can/can_stm32fd.c | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/can/Kconfig.stm32fd b/drivers/can/Kconfig.stm32fd index fd1144f8d70..5f69ba3758e 100644 --- a/drivers/can/Kconfig.stm32fd +++ b/drivers/can/Kconfig.stm32fd @@ -42,14 +42,28 @@ config CAN_STM32FD_CLOCK_SOURCE_HSE 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 diff --git a/drivers/can/can_stm32fd.c b/drivers/can/can_stm32fd.c index 4f67b29dda7..26f8c9cdac9 100644 --- a/drivers/can/can_stm32fd.c +++ b/drivers/can/can_stm32fd.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "can_mcan.h" @@ -22,6 +23,10 @@ LOG_MODULE_REGISTER(can_stm32fd, CONFIG_CAN_LOG_LEVEL); #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 @@ -62,7 +67,19 @@ static int can_stm32fd_get_core_clock(const struct device *dev, uint32_t *rate) static void can_stm32fd_clock_enable(void) { 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 + +#ifdef CONFIG_SOC_SERIES_STM32U5X + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_FDCAN1); +#else __HAL_RCC_FDCAN_CLK_ENABLE(); +#endif FDCAN_CONFIG->CKDIV = CAN_STM32FD_CLOCK_DIVISOR >> 1; }