drivers: clock control: Provide LL based clock control for stm32f4 series
This commit enables STM32Cube LL based driver for stm32f4 series. This generic driver provides a unified API to clock driver for all stm32 series. LL API allows driver to be lightweight and to keep genericity across stm32 family to ease further devlopment and maintenance. Change-Id: Ie31ae8f433313787f9c9eda77de41925721d54dd Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
parent
f3361797e3
commit
fda01e52c2
13 changed files with 150 additions and 1 deletions
|
@ -45,6 +45,9 @@ if CLOCK_CONTROL
|
|||
config CLOCK_CONTROL_STM32F4X
|
||||
def_bool y
|
||||
|
||||
config CLOCK_CONTROL_STM32_CUBE
|
||||
def_bool n
|
||||
|
||||
endif #CLOCK_CONTROL
|
||||
|
||||
if GPIO
|
||||
|
|
|
@ -53,8 +53,14 @@ static int st_stm32f4_init(struct device *arg)
|
|||
|
||||
irq_unlock(key);
|
||||
|
||||
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
|
||||
/* Update CMSIS SystemCoreClock variable (HCLK) */
|
||||
/* At reset, System core clock is set to 4MHz */
|
||||
SystemCoreClock = 4000000;
|
||||
#else
|
||||
/* Update CMSIS SystemCoreClock variable (HCLK) */
|
||||
SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
|
||||
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,13 @@ enum stm32f4x_pin_config_mode {
|
|||
|
||||
#include "soc_irq.h"
|
||||
|
||||
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
|
||||
#include <stm32f4xx_ll_utils.h>
|
||||
#include <stm32f4xx_ll_bus.h>
|
||||
#include <stm32f4xx_ll_rcc.h>
|
||||
#include <stm32f4xx_ll_system.h>
|
||||
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
|
||||
|
||||
#endif /* !_ASMLANGUAGE */
|
||||
|
||||
#endif /* _STM32F4_SOC_H_ */
|
||||
|
|
|
@ -234,10 +234,17 @@ int stm32_gpio_enable_int(int port, int pin)
|
|||
(struct stm32f4x_syscfg *)SYSCFG_BASE;
|
||||
volatile union syscfg_exticr *exticr;
|
||||
struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME);
|
||||
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
|
||||
struct stm32_pclken pclken = {
|
||||
.bus = STM32_CLOCK_BUS_APB2,
|
||||
.enr = LL_APB2_GRP1_PERIPH_SYSCFG
|
||||
};
|
||||
#else
|
||||
struct stm32f4x_pclken pclken = {
|
||||
.bus = STM32F4X_CLOCK_BUS_APB2,
|
||||
.enr = STM32F4X_CLOCK_ENABLE_SYSCFG
|
||||
};
|
||||
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
|
||||
int shift = 0;
|
||||
|
||||
/* Enable SYSCFG clock */
|
||||
|
|
|
@ -110,6 +110,52 @@ config CLOCK_STM32_PLL_MULTIPLIER
|
|||
|
||||
endif # SOC_SERIES_STM32F3X
|
||||
|
||||
if SOC_SERIES_STM32F4X
|
||||
|
||||
config CLOCK_STM32_PLLM_DIV_FACTOR
|
||||
int "Division factor for PLL VCO input clock"
|
||||
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
|
||||
default 8
|
||||
range 2 63
|
||||
help
|
||||
PLLM division factor needs to be set correctly to ensure that the VCO
|
||||
input frequency ranges from 1 to 2 MHz. It is recommended to select a
|
||||
frequency of 2 MHz to limit PLL jitter.
|
||||
Allowed values: 2-63
|
||||
|
||||
config CLOCK_STM32_PLLN_MULTIPLIER
|
||||
int "Multiplier factor for PLL VCO output clock"
|
||||
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
|
||||
default 336
|
||||
range 192 432 if SOC_STM32F401XE
|
||||
range 50 432
|
||||
help
|
||||
PLLN multiplier factor needs to be set correctly to ensure that the
|
||||
VCO output frequency is between 100 and 432 MHz, except on STM32F401
|
||||
where the frequency must be between 192 and 432 MHz.
|
||||
Allowed values: 50-432 (STM32F401: 192-432)
|
||||
|
||||
config CLOCK_STM32_PLLP_DIV_FACTOR
|
||||
int "PLL division factor for main system clock"
|
||||
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
|
||||
default 4
|
||||
range 2 8
|
||||
help
|
||||
PLLP division factor needs to be set correctly to not exceed 84MHz.
|
||||
Allowed values: 2, 4, 6, 8
|
||||
|
||||
config CLOCK_STM32_PLLQ_DIV_FACTOR
|
||||
int "Division factor for OTG FS, SDIO and RNG clocks"
|
||||
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
|
||||
default 7
|
||||
range 2 15
|
||||
help
|
||||
The USB OTG FS requires a 48MHz clock to work correctly. SDIO and RNG
|
||||
need a frequency lower than or equal to 48 MHz to work correctly.
|
||||
Allowed values: 2-15
|
||||
|
||||
endif # SOC_SERIES_STM32F4X
|
||||
|
||||
if SOC_SERIES_STM32L4X
|
||||
|
||||
config CLOCK_STM32_PLL_M_DIVISOR
|
||||
|
|
|
@ -4,6 +4,7 @@ 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_STM32F3X) += stm32f3x_ll_clock.o
|
||||
obj-$(CONFIG_SOC_SERIES_STM32F4X) += stm32f4x_ll_clock.o
|
||||
else
|
||||
obj-$(CONFIG_CLOCK_CONTROL_STM32F10X) += stm32f10x_clock.o
|
||||
obj-$(CONFIG_CLOCK_CONTROL_STM32F10X_CONN_LINE) += stm32f107xx_clock.o
|
||||
|
|
|
@ -159,6 +159,9 @@ static int stm32_clock_control_init(struct device *dev)
|
|||
/* configure clock for AHB/APB buses */
|
||||
config_bus_clk_init((LL_UTILS_ClkInitTypeDef *)&s_ClkInitStruct);
|
||||
|
||||
/* Some clocks would be activated by default */
|
||||
config_enable_default_clocks();
|
||||
|
||||
#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL
|
||||
LL_UTILS_PLLInitTypeDef s_PLLInitStruct;
|
||||
|
||||
|
@ -168,6 +171,12 @@ static int stm32_clock_control_init(struct device *dev)
|
|||
/* Disable PLL before configuration */
|
||||
LL_RCC_PLL_Disable();
|
||||
|
||||
#ifdef CONFIG_CLOCK_STM32_PLLQ_DIV_FACTOR
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ,
|
||||
CONFIG_CLOCK_STM32_PLLQ_DIV_FACTOR
|
||||
<< POSITION_VAL(RCC_PLLCFGR_PLLQ));
|
||||
#endif /* CONFIG_CLOCK_STM32_PLLQ_DIV_FACTOR */
|
||||
|
||||
#ifdef CONFIG_CLOCK_STM32_PLL_SRC_MSI
|
||||
/* Switch to PLL with MSI as clock source */
|
||||
LL_PLL_ConfigSystemClock_MSI(&s_PLLInitStruct, &s_ClkInitStruct);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define _STM32_LL_CLOCK_H_
|
||||
|
||||
void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit);
|
||||
void config_enable_default_clocks(void);
|
||||
|
||||
/* Section for functions not available in every Cube packages */
|
||||
void LL_RCC_MSI_Disable(void);
|
||||
|
|
|
@ -64,6 +64,14 @@ void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit)
|
|||
|
||||
#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
|
||||
*/
|
||||
|
|
52
drivers/clock_control/stm32f4x_ll_clock.c
Normal file
52
drivers/clock_control/stm32f4x_ll_clock.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (c) 2017 Linaro Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <soc.h>
|
||||
#include <soc_registers.h>
|
||||
#include <clock_control.h>
|
||||
#include <misc/util.h>
|
||||
#include <clock_control/stm32_clock_control.h>
|
||||
#include "stm32_ll_clock.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL
|
||||
|
||||
/* Macros to fill up division factors values */
|
||||
#define _pllm(v) LL_RCC_PLLM_DIV_ ## v
|
||||
#define pllm(v) _pllm(v)
|
||||
|
||||
#define _pllp(v) LL_RCC_PLLP_DIV_ ## v
|
||||
#define pllp(v) _pllp(v)
|
||||
|
||||
/**
|
||||
* @brief fill in pll configuration structure
|
||||
*/
|
||||
void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit)
|
||||
{
|
||||
pllinit->PLLM = pllm(CONFIG_CLOCK_STM32_PLLM_DIV_FACTOR);
|
||||
pllinit->PLLN = CONFIG_CLOCK_STM32_PLLN_MULTIPLIER;
|
||||
pllinit->PLLP = pllp(CONFIG_CLOCK_STM32_PLLP_DIV_FACTOR);
|
||||
}
|
||||
#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL */
|
||||
|
||||
/**
|
||||
* @brief Activate default clocks
|
||||
*/
|
||||
void config_enable_default_clocks(void)
|
||||
{
|
||||
/* Power Interface clock enabled by default */
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function kept for driver genericity
|
||||
*/
|
||||
void LL_RCC_MSI_Disable(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
|
@ -33,3 +33,11 @@ void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit)
|
|||
pllinit->PLLR = pllr(CONFIG_CLOCK_STM32_PLL_R_DIVISOR);
|
||||
}
|
||||
#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL */
|
||||
|
||||
/**
|
||||
* @brief Activate default clocks
|
||||
*/
|
||||
void config_enable_default_clocks(void)
|
||||
{
|
||||
/* Nothing for now */
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
|
||||
/* GPIO buses definitions */
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F3X
|
||||
#if defined(CONFIG_SOC_SERIES_STM32F3X) || defined(CONFIG_SOC_SERIES_STM32F4X)
|
||||
#define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_AHB1
|
||||
#define STM32_PERIPH_GPIOA LL_AHB1_GRP1_PERIPH_GPIOA
|
||||
#define STM32_PERIPH_GPIOB LL_AHB1_GRP1_PERIPH_GPIOB
|
||||
|
|
|
@ -19,6 +19,7 @@ endif
|
|||
ifdef CONFIG_SOC_SERIES_STM32F4X
|
||||
obj-y += stm32f4xx/drivers/src/stm32f4xx_hal.o
|
||||
obj-y += stm32f4xx/drivers/src/stm32f4xx_hal_rcc.o
|
||||
obj-$(CONFIG_CLOCK_CONTROL_STM32_CUBE) += stm32f4xx/drivers/src/stm32f4xx_ll_utils.o
|
||||
obj-$(CONFIG_PWM) += stm32f4xx/drivers/src/stm32f4xx_hal_tim.o
|
||||
obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32f4xx/drivers/src/stm32f4xx_hal_uart.o
|
||||
obj-y += stm32f4xx/soc/system_stm32f4xx.o
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue