drivers/clock_control: stm32_common: Implement clock source selection
Similarly to what was done on U5 and H7 clock_control drivers, enable device clock source selection. This is done by: -providing implementation for clock_control_configure(). -updating clock_control_get_rate() to support various possible clock sources (SYSCLK, PLLCLK, LSE, LSI, HSI, HSE). -providing enable_clock() to verify requested clock source exists and is enabled. -adding LSI and LSE device tree based initialization to set_up_fixed_clock_sources(). Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
parent
c2ee8209ab
commit
09217865ce
9 changed files with 432 additions and 161 deletions
|
@ -16,6 +16,7 @@
|
|||
#include <zephyr/sys/__assert.h>
|
||||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#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,7 +36,6 @@
|
|||
#define fn_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v
|
||||
#define mco2_prescaler(v) fn_mco2_prescaler(v)
|
||||
|
||||
|
||||
#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
|
||||
|
@ -52,6 +52,84 @@ 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)
|
||||
{
|
||||
|
@ -69,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)
|
||||
{
|
||||
|
@ -92,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,
|
||||
|
@ -120,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) {
|
||||
|
@ -153,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;
|
||||
|
@ -165,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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -206,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:
|
||||
|
@ -245,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();
|
||||
|
@ -257,8 +406,6 @@ static int set_up_plls(void)
|
|||
}
|
||||
|
||||
#endif /* STM32_PLL_ENABLED */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_up_fixed_clock_sources(void)
|
||||
|
@ -328,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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -344,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 */
|
||||
|
@ -371,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) &&
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#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 */
|
||||
}
|
||||
|
||||
return 0;
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#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 */
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#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 */
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#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);
|
||||
|
||||
LL_RCC_PLL_EnableDomain_SYS();
|
||||
|
||||
__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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#include "clock_stm32_ll_common.h"
|
||||
|
||||
|
||||
#if STM32_SYSCLK_SRC_PLL
|
||||
|
||||
/* Macros to fill up division factors values */
|
||||
|
@ -25,37 +24,54 @@
|
|||
#define z_pllr(v) LL_RCC_PLLR_DIV_ ## v
|
||||
#define pllr(v) z_pllr(v)
|
||||
|
||||
/**
|
||||
* @brief Return PLL source
|
||||
*/
|
||||
__unused
|
||||
static uint32_t get_pll_source(void)
|
||||
{
|
||||
/* 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
|
||||
*/
|
||||
int config_pll_sysclock(void)
|
||||
__unused
|
||||
void config_pll_sysclock(void)
|
||||
{
|
||||
uint32_t pll_source, pll_m, pll_n, pll_r;
|
||||
|
||||
/* 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
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#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 */
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
|
||||
#include "clock_stm32_ll_common.h"
|
||||
#include "stm32_hsem.h"
|
||||
|
||||
#if STM32_SYSCLK_SRC_PLL
|
||||
|
||||
|
@ -26,13 +25,30 @@
|
|||
#define z_pllr(v) LL_RCC_PLLR_DIV_ ## v
|
||||
#define pllr(v) z_pllr(v)
|
||||
|
||||
/**
|
||||
* @brief Return PLL source
|
||||
*/
|
||||
__unused
|
||||
static uint32_t get_pll_source(void)
|
||||
{
|
||||
/* 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
|
||||
*/
|
||||
int config_pll_sysclock(void)
|
||||
void config_pll_sysclock(void)
|
||||
{
|
||||
uint32_t pll_source, pll_m, pll_n, pll_r;
|
||||
|
||||
#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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue