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:
Erwan Gouriou 2022-04-22 11:37:28 +02:00 committed by Carles Cufí
commit 09217865ce
9 changed files with 432 additions and 161 deletions

View file

@ -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) &&

View file

@ -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);

View file

@ -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 */

View file

@ -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 */
/**

View file

@ -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 */
/**

View file

@ -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 */
/**

View file

@ -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
}

View file

@ -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 */
/**

View file

@ -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
}