From e1a90583d4a6fc77a022132bb16bea759db29996 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 29 May 2017 14:52:19 +0200 Subject: [PATCH] drivers: clock_control: provide LL based driver to stm32f1xx series Align stm32f1xx series clock driver to other parts of stm32 family. Driver support both Connectivity and Density lines of stm32f1 series, that are based on different Reset and Clock Control architectures. Signed-off-by: Erwan Gouriou --- arch/arm/soc/st_stm32/stm32f1/soc.c | 4 +- arch/arm/soc/st_stm32/stm32f1/soc.h | 7 ++ drivers/clock_control/Kconfig.stm32 | 91 ++++++++++++++++----- drivers/clock_control/Makefile | 1 + drivers/clock_control/stm32f1x_ll_clock.c | 99 +++++++++++++++++++++++ ext/hal/st/stm32cube/Kbuild | 1 + 6 files changed, 181 insertions(+), 22 deletions(-) create mode 100644 drivers/clock_control/stm32f1x_ll_clock.c diff --git a/arch/arm/soc/st_stm32/stm32f1/soc.c b/arch/arm/soc/st_stm32/stm32f1/soc.c index 43dee92884c..1a52f35a017 100644 --- a/arch/arm/soc/st_stm32/stm32f1/soc.c +++ b/arch/arm/soc/st_stm32/stm32f1/soc.c @@ -52,8 +52,8 @@ static int stm32f1_init(struct device *arg) irq_unlock(key); - /* Update CMSIS SystemCoreClock variable (HCLK) */ - SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; + /* At reset, SystemCoreClock is set to HSI()8MHz */ + SystemCoreClock = 8000000; return 0; } diff --git a/arch/arm/soc/st_stm32/stm32f1/soc.h b/arch/arm/soc/st_stm32/stm32f1/soc.h index 628e2752657..1612a8261ef 100644 --- a/arch/arm/soc/st_stm32/stm32f1/soc.h +++ b/arch/arm/soc/st_stm32/stm32f1/soc.h @@ -49,6 +49,13 @@ enum stm32f10x_pin_config_mode { #include "soc_irq.h" +#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE +#include +#include +#include +#include +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ + #endif /* !_ASMLANGUAGE */ #endif /* _STM32F1_SOC_H_ */ diff --git a/drivers/clock_control/Kconfig.stm32 b/drivers/clock_control/Kconfig.stm32 index 2e9c3ea9b82..053b940003c 100644 --- a/drivers/clock_control/Kconfig.stm32 +++ b/drivers/clock_control/Kconfig.stm32 @@ -16,10 +16,12 @@ menuconfig CLOCK_CONTROL_STM32_CUBE Enable driver for Reset & Clock Control subsystem found in STM32 family of MCUs + +if CLOCK_CONTROL_STM32_CUBE + config CLOCK_CONTROL_STM32_DEVICE_INIT_PRIORITY int "Clock Control Device Priority" default 1 - depends on CLOCK_CONTROL_STM32_CUBE help This option controls the priority of clock control device initialization. Higher priority ensures that the device @@ -28,7 +30,6 @@ config CLOCK_CONTROL_STM32_DEVICE_INIT_PRIORITY choice prompt "STM32 System Clock Source" -depends on CLOCK_CONTROL_STM32_CUBE default CLOCK_STM32_SYSCLK_SRC_PLL config CLOCK_STM32_SYSCLK_SRC_HSE @@ -50,19 +51,19 @@ endchoice config CLOCK_STM32_HSE_BYPASS bool "HSE bypass" - depends on CLOCK_CONTROL_STM32_CUBE && (CLOCK_STM32_SYSCLK_SRC_HSE || CLOCK_STM32_PLL_SRC_HSE) + depends on CLOCK_STM32_SYSCLK_SRC_HSE || CLOCK_STM32_PLL_SRC_HSE help Enable this option to bypass external high-speed clock (HSE). config CLOCK_STM32_HSE_CLOCK int "HSE clock value" - depends on CLOCK_CONTROL_STM32_CUBE && (CLOCK_STM32_SYSCLK_SRC_HSE || CLOCK_STM32_PLL_SRC_HSE) + depends on CLOCK_STM32_SYSCLK_SRC_HSE || CLOCK_STM32_PLL_SRC_HSE help Value of external high-speed clock (HSE). choice prompt "STM32 PLL Clock Source" -depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL +depends on CLOCK_STM32_SYSCLK_SRC_PLL default CLOCK_STM32_PLL_SRC_HSI config CLOCK_STM32_PLL_SRC_MSI @@ -79,13 +80,65 @@ config CLOCK_STM32_PLL_SRC_HSE bool "HSE" help Use HSE as source of PLL + +config CLOCK_STM32_PLL_SRC_PLL2 + bool "PLL2" + depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE + help + Use PLL2 as source of main PLL. This is equivalent of defining + PLL2 as source PREDIV1SCR. If not selected, default source is HSE. + endchoice +if SOC_SERIES_STM32F1X + +config CLOCK_STM32_PLL_XTPRE + bool "HSE to PLL /2 prescaler" + depends on SOC_STM32F10X_DENSITY_DEVICE && CLOCK_STM32_PLL_SRC_HSE + help + Enable this option to enable /2 prescaler on HSE to PLL clock signal + +config CLOCK_STM32_PLL_MULTIPLIER + int "PLL multiplier" + depends on CLOCK_STM32_SYSCLK_SRC_PLL + default 9 + range 2 16 if SOC_STM32F10X_DENSITY_DEVICE + range 4 9 if SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE + help + PLL multiplier, PLL output must not exceed 72MHz. Allowed values: + Density devices: 2-16 + Connectivity devices: 4 - 9 and 13 ( used for multiplication factor 6.5). + +config CLOCK_STM32_PLL_PREDIV1 + int "PREDIV1 Prescaler" + depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE && CLOCK_STM32_SYSCLK_SRC_PLL + default 1 + range 1 16 + help + PREDIV1 is PLL clock signal prescaler, allowed values: 1 - 16. + +config CLOCK_STM32_PLL2_MULTIPLIER + int "PLL2 multiplier" + depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE && CLOCK_STM32_PLL_SRC_PLL2 + default 8 + range 8 20 + help + PLL2 multiplier, allowed values: 8 - 20. 15-17-18-19 reserved + +config CLOCK_STM32_PLL2_PREDIV2 + int "PREDIV2 Prescaler" + depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE && CLOCK_STM32_PLL_SRC_PLL2 + default 1 + range 1 16 + help + PREDIV2 is PLL2 prescaler, allowed values: 1 - 16. + +endif # SOC_SERIES_STM32F1X + if SOC_SERIES_STM32F3X config CLOCK_STM32_PLL_PREDIV int "PREDIV Prescaler" - depends on CLOCK_CONTROL_STM32_CUBE default 1 range 1 16 help @@ -93,7 +146,7 @@ config CLOCK_STM32_PLL_PREDIV config CLOCK_STM32_PLL_PREDIV1 int "PREDIV1 Prescaler" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_PLL_SRC_HSE && (SOC_STM32F302XE || SOC_STM32F303XE || SOC_STM32F398XX) + depends on CLOCK_STM32_PLL_SRC_HSE && (SOC_STM32F302XE || SOC_STM32F303XE || SOC_STM32F398XX) default 1 range 1 16 help @@ -102,7 +155,7 @@ config CLOCK_STM32_PLL_PREDIV1 config CLOCK_STM32_PLL_MULTIPLIER int "PLL multiplier" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 9 range 2 16 help @@ -114,7 +167,7 @@ if SOC_SERIES_STM32F4X config CLOCK_STM32_PLL_M_DIVISOR int "Division factor for PLL VCO input clock" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 8 range 2 63 help @@ -125,7 +178,7 @@ config CLOCK_STM32_PLL_M_DIVISOR config CLOCK_STM32_PLL_N_MULTIPLIER int "Multiplier factor for PLL VCO output clock" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 336 range 192 432 if SOC_STM32F401XE range 50 432 @@ -137,7 +190,7 @@ config CLOCK_STM32_PLL_N_MULTIPLIER config CLOCK_STM32_PLL_P_DIVISOR int "PLL division factor for main system clock" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 4 range 2 8 help @@ -146,7 +199,7 @@ config CLOCK_STM32_PLL_P_DIVISOR config CLOCK_STM32_PLL_Q_DIVISOR int "Division factor for OTG FS, SDIO and RNG clocks" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 7 range 2 15 help @@ -160,7 +213,7 @@ if SOC_SERIES_STM32L4X config CLOCK_STM32_PLL_M_DIVISOR int "PLL divisor" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 1 range 1 8 help @@ -169,7 +222,7 @@ config CLOCK_STM32_PLL_M_DIVISOR config CLOCK_STM32_PLL_N_MULTIPLIER int "PLL multiplier" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 20 range 8 86 help @@ -178,7 +231,7 @@ config CLOCK_STM32_PLL_N_MULTIPLIER config CLOCK_STM32_PLL_P_DIVISOR int "PLL P Divisor" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 7 range 0 17 help @@ -186,7 +239,7 @@ config CLOCK_STM32_PLL_P_DIVISOR config CLOCK_STM32_PLL_Q_DIVISOR int "PLL Q Divisor" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 2 range 0 8 help @@ -194,7 +247,7 @@ config CLOCK_STM32_PLL_Q_DIVISOR config CLOCK_STM32_PLL_R_DIVISOR int "PLL R Divisor" - depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL + depends on CLOCK_STM32_SYSCLK_SRC_PLL default 4 range 0 8 help @@ -204,7 +257,6 @@ endif # SOC_SERIES_STM32L4X config CLOCK_STM32_AHB_PRESCALER int "AHB prescaler" - depends on CLOCK_CONTROL_STM32_CUBE default 0 range 0 512 help @@ -213,7 +265,6 @@ config CLOCK_STM32_AHB_PRESCALER config CLOCK_STM32_APB1_PRESCALER int "APB1 prescaler" - depends on CLOCK_CONTROL_STM32_CUBE default 1 range 1 16 help @@ -222,11 +273,11 @@ config CLOCK_STM32_APB1_PRESCALER config CLOCK_STM32_APB2_PRESCALER int "APB2 prescaler" - depends on CLOCK_CONTROL_STM32_CUBE default 1 range 1 16 help APB2 High speed clock (PCLK2) prescaler, allowed values: 1, 2, 4, 8, 16 +endif # CLOCK_CONTROL_STM32_CUBE endif # SOC_FAMILY_STM32 diff --git a/drivers/clock_control/Makefile b/drivers/clock_control/Makefile index fc9273a8906..fa8934b78ad 100644 --- a/drivers/clock_control/Makefile +++ b/drivers/clock_control/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o ifeq ($(CONFIG_CLOCK_CONTROL_STM32_CUBE),y) obj-y += stm32_ll_clock.o obj-$(CONFIG_SOC_SERIES_STM32L4X) += stm32l4x_ll_clock.o +obj-$(CONFIG_SOC_SERIES_STM32F1X) += stm32f1x_ll_clock.o obj-$(CONFIG_SOC_SERIES_STM32F3X) += stm32f3x_ll_clock.o obj-$(CONFIG_SOC_SERIES_STM32F4X) += stm32f4x_ll_clock.o else diff --git a/drivers/clock_control/stm32f1x_ll_clock.c b/drivers/clock_control/stm32f1x_ll_clock.c new file mode 100644 index 00000000000..92c012403b7 --- /dev/null +++ b/drivers/clock_control/stm32f1x_ll_clock.c @@ -0,0 +1,99 @@ +/* + * + * Copyright (c) 2017 Linaro Limited. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include +#include +#include +#include +#include +#include "stm32_ll_clock.h" + + +#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL + +/* + * Select PLL source for STM32F1 Connectivity line devices (STM32F105xx and + * STM32F107xx). + * Both flags are defined in STM32Cube LL API. Keep only the selected one. + */ +#ifdef CONFIG_CLOCK_STM32_PLL_SRC_PLL2 +#undef RCC_PREDIV1_SOURCE_HSE +#else +#undef RCC_PREDIV1_SOURCE_PLL2 +#endif /* CONFIG_CLOCK_STM32_PLL_SRC_PLL2 */ + + +/** + * @brief fill in pll configuration structure + */ +void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit) +{ + /* + * PLLMUL on SOC_STM32F10X_DENSITY_DEVICE + * 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 + * + * PLLMUL on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE + * 4 -> LL_RCC_PLL_MUL_4 -> 0x00080000 + * ... + * 9 -> LL_RCC_PLL_MUL_9 -> 0x001C0000 + * 13 -> LL_RCC_PLL_MUL_6_5 -> 0x00340000 + */ + pllinit->PLLMul = ((CONFIG_CLOCK_STM32_PLL_MULTIPLIER - 2) + << RCC_CFGR_PLLMULL_Pos); + +#ifdef CONFIG_SOC_STM32F10X_DENSITY_DEVICE + /* PLL prediv */ +#ifdef CONFIG_CLOCK_STM32_PLL_XTPRE + /* + * SOC_STM32F10X_DENSITY_DEVICE: + * PLLXPTRE (depends on PLL source HSE) + * HSE/2 used as PLL source + */ + pllinit->Prediv = LL_RCC_PREDIV_DIV_2; +#else + /* + * SOC_STM32F10X_DENSITY_DEVICE: + * PLLXPTRE (depends on PLL source HSE) + * HSE used as direct PLL source + */ + pllinit->Prediv = LL_RCC_PREDIV_DIV_1; +#endif /* CONFIG_CLOCK_STM32_PLL_XTPRE */ +#else + /* + * SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE + * 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 + */ + pllinit->Prediv = CONFIG_CLOCK_STM32_PLL_PREDIV1 - 1; +#endif /* CONFIG_SOC_STM32F10X_DENSITY_DEVICE */ +} + +#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL */ + +/** + * @brief Activate default clocks + */ +void config_enable_default_clocks(void) +{ + /* Nothing for now */ +} + +/** + * @brief Function kept for driver genericity + */ +void LL_RCC_MSI_Disable(void) +{ + /* Do nothing */ +} diff --git a/ext/hal/st/stm32cube/Kbuild b/ext/hal/st/stm32cube/Kbuild index 5d49ef33e37..a0c8be8f2fd 100644 --- a/ext/hal/st/stm32cube/Kbuild +++ b/ext/hal/st/stm32cube/Kbuild @@ -3,6 +3,7 @@ ifdef CONFIG_HAS_STM32CUBE ifdef CONFIG_SOC_SERIES_STM32F1X obj-y += stm32f1xx/drivers/src/stm32f1xx_hal.o obj-y += stm32f1xx/drivers/src/stm32f1xx_hal_rcc.o +obj-$(CONFIG_CLOCK_CONTROL_STM32_CUBE) += stm32f1xx/drivers/src/stm32f1xx_ll_utils.o obj-$(CONFIG_PWM) += stm32f1xx/drivers/src/stm32f1xx_hal_tim.o obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32f1xx/drivers/src/stm32f1xx_hal_uart.o obj-y += stm32f1xx/soc/system_stm32f1xx.o