drivers: clock: stm32 clock driver supporting the stm32H7RS

Introduce the stm32h7RS serie to the clock_controller,
based on the stm32h7 clock driver
Datasheet DS14359 rev 1 gives CPU max freq of 500MHz

Signed-off-by: Francois Ramu <francois.ramu@st.com>
This commit is contained in:
Francois Ramu 2024-02-16 12:17:59 +01:00 committed by Carles Cufí
parent 332eb17995
commit e6ebb044ac
7 changed files with 389 additions and 15 deletions

View File

@ -38,6 +38,8 @@ if(CONFIG_SOC_SERIES_STM32MP1X)
zephyr_library_sources(clock_stm32_ll_mp1.c)
elseif(CONFIG_SOC_SERIES_STM32H7X)
zephyr_library_sources(clock_stm32_ll_h7.c)
elseif(CONFIG_SOC_SERIES_STM32H7RSX)
zephyr_library_sources(clock_stm32_ll_h7.c)
elseif(CONFIG_SOC_SERIES_STM32H5X)
zephyr_library_sources(clock_stm32_ll_h5.c)
elseif(CONFIG_SOC_SERIES_STM32U5X)

View File

@ -9,7 +9,7 @@ menuconfig CLOCK_CONTROL_STM32_CUBE
depends on SOC_FAMILY_STM32
select USE_STM32_LL_UTILS
select USE_STM32_LL_RCC if (SOC_SERIES_STM32MP1X || SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X)
SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X)
select RUNTIME_NMI if ($(dt_nodelabel_enabled,clk_hse) && \
$(dt_nodelabel_has_prop,clk_hse,css-enabled))
help
@ -69,6 +69,7 @@ config CLOCK_STM32_MCO1_SRC_LSE
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use LSE as source of MCO1
@ -80,6 +81,7 @@ config CLOCK_STM32_MCO1_SRC_HSE
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use HSE as source of MCO1
@ -102,6 +104,7 @@ config CLOCK_STM32_MCO1_SRC_HSI
SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use HSI as source of MCO1
@ -116,6 +119,7 @@ config CLOCK_STM32_MCO1_SRC_HSI48
bool "HSI48"
depends on SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use HSI48 as source of MCO1
@ -129,6 +133,7 @@ config CLOCK_STM32_MCO1_SRC_PLLCLK
config CLOCK_STM32_MCO1_SRC_PLLQCLK
bool "PLLQ"
depends on SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use PLLQ as source of MCO1
@ -171,11 +176,12 @@ config CLOCK_STM32_MCO1_DIV
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X \
)
default 1
range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X
range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32H5X
range 1 16 if SOC_SERIES_STM32L4X
help
Prescaler for MCO1 output clock
@ -194,6 +200,7 @@ config CLOCK_STM32_MCO2_SRC_SYSCLK
depends on SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use SYSCLK as source of MCO2
@ -209,6 +216,7 @@ config CLOCK_STM32_MCO2_SRC_HSE
depends on SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use HSE as source of MCO2
@ -216,6 +224,7 @@ config CLOCK_STM32_MCO2_SRC_HSE
config CLOCK_STM32_MCO2_SRC_LSI
bool "LSI"
depends on SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use LSI as source of MCO2
@ -223,6 +232,7 @@ config CLOCK_STM32_MCO2_SRC_LSI
config CLOCK_STM32_MCO2_SRC_CSI
bool "CSI"
depends on SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use CSI as source of MCO2
@ -236,6 +246,7 @@ config CLOCK_STM32_MCO2_SRC_PLLCLK
config CLOCK_STM32_MCO2_SRC_PLLPCLK
bool "PLLPCLK"
depends on SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use PLLPCLK as source of MC02
@ -243,6 +254,7 @@ config CLOCK_STM32_MCO2_SRC_PLLPCLK
config CLOCK_STM32_MCO2_SRC_PLL2PCLK
bool "PLL2PCLK"
depends on SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX || \
SOC_SERIES_STM32H5X
help
Use PLL2PCLK as source of MC02
@ -254,11 +266,12 @@ config CLOCK_STM32_MCO2_DIV
SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H5X || \
SOC_SERIES_STM32H7X \
SOC_SERIES_STM32H7X || \
SOC_SERIES_STM32H7RSX \
)
default 1
range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X
range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32H5X
help
Prescaler for MCO2 output clock

View File

@ -21,7 +21,11 @@
/* Macros to fill up prescaler values */
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
#define z_hsi_divider(v) LL_RCC_HSI_DIV_ ## v
#else
#define z_hsi_divider(v) LL_RCC_HSI_DIV ## v
#endif
#define hsi_divider(v) z_hsi_divider(v)
#define z_sysclk_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
@ -42,6 +46,9 @@
#define z_apb4_prescaler(v) LL_RCC_APB4_DIV_ ## v
#define apb4_prescaler(v) z_apb4_prescaler(v)
#define z_apb5_prescaler(v) LL_RCC_APB5_DIV_ ## v
#define apb5_prescaler(v) z_apb5_prescaler(v)
/* Macro to check for clock feasibility */
/* It is Cortex M7's responsibility to setup clock tree */
/* This check should only be performed for the M7 core code */
@ -81,12 +88,21 @@
#endif
/* ARM Sys CPU Clock before HPRE prescaler */
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
#define SYSCLK_FREQ ((SYSCLKSRC_FREQ)/(STM32_D1CPRE))
#define AHB_FREQ ((SYSCLK_FREQ)/(STM32_HPRE))
#define APB1_FREQ ((AHB_FREQ)/(STM32_PPRE1))
#define APB2_FREQ ((AHB_FREQ)/(STM32_PPRE2))
#define APB4_FREQ ((AHB_FREQ)/(STM32_PPRE4))
#define APB5_FREQ ((AHB_FREQ)/(STM32_PPRE5))
#else
#define SYSCLK_FREQ ((SYSCLKSRC_FREQ)/(STM32_D1CPRE))
#define AHB_FREQ ((SYSCLK_FREQ)/(STM32_HPRE))
#define APB1_FREQ ((AHB_FREQ)/(STM32_D2PPRE1))
#define APB2_FREQ ((AHB_FREQ)/(STM32_D2PPRE2))
#define APB3_FREQ ((AHB_FREQ)/(STM32_D1PPRE))
#define APB4_FREQ ((AHB_FREQ)/(STM32_D3PPRE))
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
/* Datasheet maximum frequency definitions */
#if defined(CONFIG_SOC_STM32H743XX) ||\
@ -112,6 +128,11 @@
#define SYSCLK_FREQ_MAX 280000000UL
#define AHB_FREQ_MAX 280000000UL
#define APBx_FREQ_MAX 140000000UL
#elif defined(CONFIG_SOC_SERIES_STM32H7RSX)
/* All h7RS SoC with maximum 500MHz SYSCLK (refer to Datasheet DS14359 rev 1) */
#define SYSCLK_FREQ_MAX 500000000UL
#define AHB_FREQ_MAX 250000000UL
#define APBx_FREQ_MAX 125000000UL
#else
/* Default: All h7 SoC with maximum 280MHz SYSCLK */
#define SYSCLK_FREQ_MAX 280000000UL
@ -154,7 +175,7 @@
* So, changing this prescaler is not allowed until it is made possible to
* use them independently in zephyr clock subsystem.
*/
#error "D1CPRE presacler can't be higher than 1"
#error "D1CPRE prescaler can't be higher than 1"
#endif
#endif /* CONFIG_CPU_CORTEX_M7 */
@ -255,7 +276,11 @@ static int32_t prepare_regulator_voltage_scale(void)
/* Make sure to put the CPU in highest Voltage scale during clock configuration */
/* Highest voltage is SCALE0 */
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
while (LL_PWR_IsActiveFlag_VOSRDY() == 0) {
#else
while (LL_PWR_IsActiveFlag_VOS() == 0) {
#endif
}
return 0;
}
@ -290,8 +315,12 @@ static int32_t optimize_regulator_voltage_scale(uint32_t sysclk_freq)
LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
#endif
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
while (LL_PWR_IsActiveFlag_VOSRDY() == 0) {
#else
while (LL_PWR_IsActiveFlag_VOS() == 0) {
}
#endif
};
return 0;
}
@ -448,10 +477,17 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock,
#else
uint32_t ahb_clock = get_bus_clock(SystemCoreClock, STM32_HPRE);
#endif
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_PPRE1);
uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_PPRE2);
uint32_t apb4_clock = get_bus_clock(ahb_clock, STM32_PPRE4);
uint32_t apb5_clock = get_bus_clock(ahb_clock, STM32_PPRE5);
#else
uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_D2PPRE1);
uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_D2PPRE2);
uint32_t apb3_clock = get_bus_clock(ahb_clock, STM32_D1PPRE);
uint32_t apb4_clock = get_bus_clock(ahb_clock, STM32_D3PPRE);
#endif
ARG_UNUSED(clock);
@ -469,12 +505,22 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock,
case STM32_CLOCK_BUS_APB2:
*rate = apb2_clock;
break;
#if !defined(CONFIG_SOC_SERIES_STM32H7RSX)
case STM32_CLOCK_BUS_APB3:
*rate = apb3_clock;
break;
#endif /* !CONFIG_SOC_SERIES_STM32H7RSX */
case STM32_CLOCK_BUS_APB4:
*rate = apb4_clock;
break;
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
case STM32_CLOCK_BUS_APB5:
*rate = apb5_clock;
break;
case STM32_CLOCK_BUS_AHB5:
*rate = ahb_clock;
break;
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
case STM32_SRC_SYSCLK:
*rate = get_hclk_frequency();
break;
@ -522,6 +568,15 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock,
STM32_PLL_N_MULTIPLIER,
STM32_PLL_R_DIVISOR);
break;
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
case STM32_SRC_PLL1_S:
*rate = get_pllout_frequency(get_pllsrc_frequency(),
STM32_PLL_M_DIVISOR,
STM32_PLL_N_MULTIPLIER,
STM32_PLL_S_DIVISOR);
break;
/* PLL 1 has no T-divider */
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
#endif /* STM32_PLL_ENABLED */
#if defined(STM32_PLL2_ENABLED)
case STM32_SRC_PLL2_P:
@ -542,6 +597,20 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock,
STM32_PLL2_N_MULTIPLIER,
STM32_PLL2_R_DIVISOR);
break;
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
case STM32_SRC_PLL2_S:
*rate = get_pllout_frequency(get_pllsrc_frequency(),
STM32_PLL2_M_DIVISOR,
STM32_PLL2_N_MULTIPLIER,
STM32_PLL2_S_DIVISOR);
break;
case STM32_SRC_PLL2_T:
*rate = get_pllout_frequency(get_pllsrc_frequency(),
STM32_PLL2_M_DIVISOR,
STM32_PLL2_N_MULTIPLIER,
STM32_PLL2_T_DIVISOR);
break;
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
#endif /* STM32_PLL2_ENABLED */
#if defined(STM32_PLL3_ENABLED)
case STM32_SRC_PLL3_P:
@ -562,6 +631,15 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock,
STM32_PLL3_N_MULTIPLIER,
STM32_PLL3_R_DIVISOR);
break;
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
case STM32_SRC_PLL3_S:
*rate = get_pllout_frequency(get_pllsrc_frequency(),
STM32_PLL3_M_DIVISOR,
STM32_PLL3_N_MULTIPLIER,
STM32_PLL3_S_DIVISOR);
break;
/* PLL 3 has no T-divider */
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
#endif /* STM32_PLL3_ENABLED */
default:
return -ENOTSUP;
@ -739,6 +817,12 @@ static int set_up_plls(void)
LL_RCC_PLL1R_Enable();
}
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
if (IS_ENABLED(STM32_PLL_S_ENABLED)) {
LL_RCC_PLL1_SetS(STM32_PLL_S_DIVISOR);
LL_RCC_PLL1S_Enable();
}
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
LL_RCC_PLL1_Enable();
while (LL_RCC_PLL1_IsReady() != 1U) {
}
@ -777,6 +861,18 @@ static int set_up_plls(void)
LL_RCC_PLL2R_Enable();
}
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
if (IS_ENABLED(STM32_PLL2_S_ENABLED)) {
LL_RCC_PLL2_SetS(STM32_PLL2_S_DIVISOR);
LL_RCC_PLL2S_Enable();
}
if (IS_ENABLED(STM32_PLL2_T_ENABLED)) {
LL_RCC_PLL2_SetT(STM32_PLL2_T_DIVISOR);
LL_RCC_PLL2T_Enable();
}
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
LL_RCC_PLL2_Enable();
while (LL_RCC_PLL2_IsReady() != 1U) {
}
@ -815,6 +911,13 @@ static int set_up_plls(void)
LL_RCC_PLL3R_Enable();
}
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
if (IS_ENABLED(STM32_PLL3_S_ENABLED)) {
LL_RCC_PLL3_SetS(STM32_PLL3_S_DIVISOR);
LL_RCC_PLL3S_Enable();
}
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
LL_RCC_PLL3_Enable();
while (LL_RCC_PLL3_IsReady() != 1U) {
}
@ -830,6 +933,91 @@ static int set_up_plls(void)
return 0;
}
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
/* adapted from the stm32cube SystemCoreClockUpdate*/
void stm32_system_clock_update(void)
{
uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc;
float_t pllfracn, pllvco;
/* Get SYSCLK source */
switch (RCC->CFGR & RCC_CFGR_SWS) {
case 0x00: /* HSI used as system clock source (default after reset) */
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)
>> RCC_CR_HSIDIV_Pos));
break;
case 0x08: /* CSI used as system clock source */
sysclk = CSI_VALUE;
break;
case 0x10: /* HSE used as system clock source */
sysclk = HSE_VALUE;
break;
case 0x18: /* PLL1 used as system clock source */
/*
* PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
* SYSCLK = PLL1_VCO / PLL1R
*/
pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos);
if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U) {
pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)
>> RCC_PLL1FRACR_FRACN_Pos));
} else {
pllfracn = (float_t)0U;
}
if (pllm != 0U) {
switch (pllsource) {
case 0x02: /* HSE used as PLL1 clock source */
pllvco = ((float_t)HSE_VALUE / (float_t)pllm) *
((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) +
(pllfracn/(float_t)0x2000) + (float_t)1);
break;
case 0x01: /* CSI used as PLL1 clock source */
pllvco = ((float_t)CSI_VALUE / (float_t)pllm) *
((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) +
(pllfracn/(float_t)0x2000) + (float_t)1);
break;
case 0x00: /* HSI used as PLL1 clock source */
default:
hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >>
RCC_CR_HSIDIV_Pos));
pllvco = ((float_t)hsivalue / (float_t)pllm) *
((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) +
(pllfracn/(float_t)0x2000) + (float_t)1);
break;
}
pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >>
RCC_PLL1DIVR1_DIVP_Pos) + 1U);
sysclk = (uint32_t)(float_t)(pllvco/(float_t)pllp);
} else {
sysclk = 0U;
}
break;
default: /* Unexpected, default to HSI used as system clk source (default after reset) */
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
break;
}
/* system clock frequency : CM7 CPU frequency */
core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE);
if (core_presc >= 8U) {
SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U));
} else {
SystemCoreClock = sysclk;
}
}
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
int stm32_clock_control_init(const struct device *dev)
{
int r = 0;
@ -843,10 +1031,10 @@ int stm32_clock_control_init(const struct device *dev)
defined(CONFIG_SOC_STM32H7B0XX) || defined(CONFIG_SOC_STM32H7B0XXQ) || \
defined(CONFIG_SOC_STM32H7B3XX) || defined(CONFIG_SOC_STM32H7B3XXQ)
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_HSEM);
#else
#elif !defined(CONFIG_SOC_SERIES_STM32H7RSX)
/* The stm32h7RS serie has no HSEM peripheral */
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_HSEM);
#endif
z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
/* Configure MCO1/MCO2 based on Kconfig */
@ -871,22 +1059,38 @@ int stm32_clock_control_init(const struct device *dev)
STM32_HPRE);
/* Set flash latency */
/* AHB/AXI/HCLK clock is SYSCLK / HPRE */
/* If freq increases, set flash latency before any clock setting */
if (new_hclk_freq > old_hclk_freq) {
LL_SetFlashLatency(new_hclk_freq);
}
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
/*
* The default Flash latency is 3 WS which is not enough,
* set higher and correct later if needed
*/
LL_FLASH_SetLatency(LL_FLASH_LATENCY_6);
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
/* Preset the prescalers prior to choosing SYSCLK */
/* Prevents APB clock to go over limits */
/* Set buses (Sys,AHB, APB1, APB2 & APB4) prescalers */
LL_RCC_SetSysPrescaler(sysclk_prescaler(STM32_D1CPRE));
LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_HPRE));
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_PPRE1));
LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_PPRE2));
LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_PPRE4));
LL_RCC_SetAPB5Prescaler(apb5_prescaler(STM32_PPRE5));
#else
LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_D2PPRE1));
LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_D2PPRE2));
LL_RCC_SetAPB3Prescaler(apb3_prescaler(STM32_D1PPRE));
LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_D3PPRE));
#endif
/* Set up sys clock */
if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
/* Set PLL1 as System Clock Source */

View File

@ -33,7 +33,8 @@
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLQCLK
#if (CONFIG_SOC_SERIES_STM32G0X || CONFIG_SOC_SERIES_STM32WLX)
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLQCLK
#elif (CONFIG_SOC_SERIES_STM32H5X || CONFIG_SOC_SERIES_STM32H7X)
#elif (CONFIG_SOC_SERIES_STM32H5X || \
CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32H7RSX)
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLL1QCLK
#else
#error "PLLQCLK is not a valid clock source on your SOC"

View File

@ -30,11 +30,11 @@ properties:
div-s:
type: int
description: |
PLL division factor for pllx_s_ck
PLL division factor for pllx_s_ck : valid for PLL1, 2, 3
Valid range: 1 - 8
div-t:
type: int
description: |
PLL division factor for pllx_t_ck
PLL division factor for pllx_t_ck : valid for PLL2
Valid range: 1 - 8

View File

@ -44,6 +44,8 @@
#include <zephyr/dt-bindings/clock/stm32h5_clock.h>
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
#include <zephyr/dt-bindings/clock/stm32h7_clock.h>
#elif defined(CONFIG_SOC_SERIES_STM32H7RSX)
#include <zephyr/dt-bindings/clock/stm32h7rs_clock.h>
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
#include <zephyr/dt-bindings/clock/stm32u5_clock.h>
#elif defined(CONFIG_SOC_SERIES_STM32WBAX)
@ -61,6 +63,7 @@
#define STM32_APB1_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb1_prescaler)
#define STM32_APB2_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb2_prescaler)
#define STM32_APB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb3_prescaler)
#define STM32_APB5_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb5_prescaler)
#define STM32_APB7_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb7_prescaler)
#define STM32_AHB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
#define STM32_AHB4_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
@ -86,13 +89,22 @@
#define STM32_ADC12_PRESCALER DT_PROP(DT_NODELABEL(rcc), adc12_prescaler)
#define STM32_ADC34_PRESCALER DT_PROP(DT_NODELABEL(rcc), adc34_prescaler)
/** STM2H7 specifics RCC dividers */
/** STM2H7RS specific RCC dividers */
#if defined(CONFIG_SOC_SERIES_STM32H7RSX)
#define STM32_D1CPRE DT_PROP(DT_NODELABEL(rcc), dcpre)
#define STM32_HPRE DT_PROP(DT_NODELABEL(rcc), hpre)
#define STM32_PPRE1 DT_PROP(DT_NODELABEL(rcc), ppre1)
#define STM32_PPRE2 DT_PROP(DT_NODELABEL(rcc), ppre2)
#define STM32_PPRE4 DT_PROP(DT_NODELABEL(rcc), ppre4)
#define STM32_PPRE5 DT_PROP(DT_NODELABEL(rcc), ppre5)
#else
#define STM32_D1CPRE DT_PROP(DT_NODELABEL(rcc), d1cpre)
#define STM32_HPRE DT_PROP(DT_NODELABEL(rcc), hpre)
#define STM32_D2PPRE1 DT_PROP(DT_NODELABEL(rcc), d2ppre1)
#define STM32_D2PPRE2 DT_PROP(DT_NODELABEL(rcc), d2ppre2)
#define STM32_D1PPRE DT_PROP(DT_NODELABEL(rcc), d1ppre)
#define STM32_D3PPRE DT_PROP(DT_NODELABEL(rcc), d3ppre)
#endif /* CONFIG_SOC_SERIES_STM32H7RSX */
/** STM2WBA specifics RCC dividers */
#define STM32_AHB5_DIV DT_PROP(DT_NODELABEL(rcc), ahb5_div)
@ -133,7 +145,8 @@
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32u5_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32wb_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32wba_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7_pll_clock, okay)
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7rs_pll_clock, okay)
#define STM32_PLL_ENABLED 1
#define STM32_PLL_M_DIVISOR DT_PROP(DT_NODELABEL(pll), div_m)
#define STM32_PLL_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll), mul_n)
@ -143,6 +156,8 @@
#define STM32_PLL_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_q, 1)
#define STM32_PLL_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_r)
#define STM32_PLL_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_r, 1)
#define STM32_PLL_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_s)
#define STM32_PLL_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_s, 1)
#define STM32_PLL_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), fracn)
#define STM32_PLL_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll), fracn, 1)
#endif
@ -164,7 +179,8 @@
#endif
#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32u5_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7_pll_clock, okay)
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7rs_pll_clock, okay)
#define STM32_PLL2_ENABLED 1
#define STM32_PLL2_M_DIVISOR DT_PROP(DT_NODELABEL(pll2), div_m)
#define STM32_PLL2_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll2), mul_n)
@ -174,12 +190,17 @@
#define STM32_PLL2_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_q, 1)
#define STM32_PLL2_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_r)
#define STM32_PLL2_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_r, 1)
#define STM32_PLL2_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_s)
#define STM32_PLL2_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_s, 1)
#define STM32_PLL2_T_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_t)
#define STM32_PLL2_T_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_t, 1)
#define STM32_PLL2_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), fracn)
#define STM32_PLL2_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll2), fracn, 1)
#endif
#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32u5_pll_clock, okay)
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32u5_pll_clock, okay) || \
DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7rs_pll_clock, okay)
#define STM32_PLL3_ENABLED 1
#define STM32_PLL3_M_DIVISOR DT_PROP(DT_NODELABEL(pll3), div_m)
#define STM32_PLL3_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll3), mul_n)
@ -189,6 +210,8 @@
#define STM32_PLL3_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_q, 1)
#define STM32_PLL3_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_r)
#define STM32_PLL3_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_r, 1)
#define STM32_PLL3_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_s)
#define STM32_PLL3_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_s, 1)
#define STM32_PLL3_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), fracn)
#define STM32_PLL3_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll3), fracn, 1)
#endif

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2024 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7RS_CLOCK_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7RS_CLOCK_H_
#include "stm32_common_clocks.h"
/** Domain clocks */
/* RM0477 */
/** System clock */
/* defined in stm32_common_clocks.h */
/** Fixed clocks */
/* Low speed clocks defined in stm32_common_clocks.h */
#define STM32_SRC_HSE (STM32_SRC_LSI + 1)
#define STM32_SRC_HSI48 (STM32_SRC_HSE + 1)
#define STM32_SRC_HSI_KER (STM32_SRC_HSI48 + 1) /* HSI + HSIKERON */
#define STM32_SRC_CSI_KER (STM32_SRC_HSI_KER + 1) /* CSI + CSIKERON */
/** PLL outputs */
#define STM32_SRC_PLL1_P (STM32_SRC_CSI_KER + 1)
#define STM32_SRC_PLL1_Q (STM32_SRC_PLL1_P + 1)
#define STM32_SRC_PLL1_R (STM32_SRC_PLL1_Q + 1)
#define STM32_SRC_PLL1_S (STM32_SRC_PLL1_R + 1)
#define STM32_SRC_PLL2_P (STM32_SRC_PLL1_S + 1)
#define STM32_SRC_PLL2_Q (STM32_SRC_PLL2_P + 1)
#define STM32_SRC_PLL2_R (STM32_SRC_PLL2_Q + 1)
#define STM32_SRC_PLL2_S (STM32_SRC_PLL2_R + 1)
#define STM32_SRC_PLL2_T (STM32_SRC_PLL2_S + 1)
#define STM32_SRC_PLL3_P (STM32_SRC_PLL2_T + 1)
#define STM32_SRC_PLL3_Q (STM32_SRC_PLL3_P + 1)
#define STM32_SRC_PLL3_R (STM32_SRC_PLL3_Q + 1)
#define STM32_SRC_PLL3_S (STM32_SRC_PLL3_R + 1)
/** Clock muxes */
#define STM32_SRC_CKPER (STM32_SRC_PLL3_S + 1)
/** Others: Not yet supported */
/** Bus clocks */
#define STM32_CLOCK_BUS_AHB1 0x138
#define STM32_CLOCK_BUS_AHB2 0x13C
#define STM32_CLOCK_BUS_AHB3 0x158
#define STM32_CLOCK_BUS_AHB4 0x140
#define STM32_CLOCK_BUS_AHB5 0x134
#define STM32_CLOCK_BUS_APB1 0x148
#define STM32_CLOCK_BUS_APB1_2 0x14C
#define STM32_CLOCK_BUS_APB2 0x150
#define STM32_CLOCK_BUS_APB4 0x154
#define STM32_CLOCK_BUS_APB5 0x144
#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB5
#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_AHB3
#define STM32_CLOCK_REG_MASK 0xFFU
#define STM32_CLOCK_REG_SHIFT 0U
#define STM32_CLOCK_SHIFT_MASK 0x1FU
#define STM32_CLOCK_SHIFT_SHIFT 8U
#define STM32_CLOCK_MASK_MASK 0x7U
#define STM32_CLOCK_MASK_SHIFT 13U
#define STM32_CLOCK_VAL_MASK 0x7U
#define STM32_CLOCK_VAL_SHIFT 16U
/**
* @brief STM32H7RS clock configuration bit field.
*
* - reg (0/1) [ 0 : 7 ]
* - shift (0..31) [ 8 : 12 ]
* - mask (0x1, 0x3, 0x7) [ 13 : 15 ]
* - val (0..3) [ 16 : 18 ]
*
* @param reg RCC_DxCCIP register offset
* @param shift Position within RCC_DxCCIP.
* @param mask Mask for the RCC_DxCCIP field.
* @param val Clock value (0, 1, 2 or 3).
*/
#define STM32_CLOCK(val, mask, shift, reg) \
((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \
(((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \
(((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \
(((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT))
/** @brief RCC_DxCCIP register offset (RM0477.pdf) */
#define D1CCIPR_REG 0x4C
#define D2CCIPR_REG 0x50
#define D3CCIPR_REG 0x54
#define D4CCIPR_REG 0x58
/** @brief RCC_BDCR register offset */
#define BDCR_REG 0x70
/** @brief Device domain clocks selection helpers (RM0477.pdf) */
/* TODO to be completed */
/** D1CCIPR devices */
#define FMC_SEL(val) STM32_CLOCK(val, 3, 0, D1CCIPR_REG)
#define SDMMC_SEL(val) STM32_CLOCK(val, 1, 2, D1CCIPR_REG)
#define XSPI1_SEL(val) STM32_CLOCK(val, 3, 4, D1CCIPR_REG)
#define XSPI2_SEL(val) STM32_CLOCK(val, 3, 6, D1CCIPR_REG)
#define ADC_SEL(val) STM32_CLOCK(val, 3, 24, D1CCIPR_REG)
#define CKPER_SEL(val) STM32_CLOCK(val, 3, 28, D1CCIPR_REG)
/** D2CCIPR devices */
#define USART234578_SEL(val) STM32_CLOCK(val, 7, 0, D2CCIPR_REG)
#define SPI23_SEL(val) STM32_CLOCK(val, 7, 4, D2CCIPR_REG)
#define I2C23_SEL(val) STM32_CLOCK(val, 3, 8, D2CCIPR_REG)
#define I2C1_SEL(val) STM32_CLOCK(val, 3, 12, D2CCIPR_REG)
#define I3C1_SEL(val) STM32_CLOCK(val, 3, 12, D2CCIPR_REG)
#define LPTIM1_SEL(val) STM32_CLOCK(val, 7, 16, D2CCIPR_REG)
#define FDCAN_SEL(val) STM32_CLOCK(val, 3, 22, D2CCIPR_REG)
/** D3CCIPR devices */
#define USART1_SEL(val) STM32_CLOCK(val, 7, 0, D3CCIPR_REG)
#define SPI45_SEL(val) STM32_CLOCK(val, 7, 4, D3CCIPR_REG)
#define SPI1_SEL(val) STM32_CLOCK(val, 7, 8, D3CCIPR_REG)
#define SAI1_SEL(val) STM32_CLOCK(val, 7, 16, D3CCIPR_REG)
#define SAI2_SEL(val) STM32_CLOCK(val, 7, 20, D3CCIPR_REG)
/** D4CCIPR devices */
#define LPUART1_SEL(val) STM32_CLOCK(val, 7, 0, D4CCIPR_REG)
#define SPI6_SEL(val) STM32_CLOCK(val, 7, 4, D4CCIPR_REG)
#define LPTIM23_SEL(val) STM32_CLOCK(val, 7, 8, D4CCIPR_REG)
#define LPTIM45_SEL(val) STM32_CLOCK(val, 7, 12, D4CCIPR_REG)
/** BDCR devices */
#define RTC_SEL(val) STM32_CLOCK(val, 3, 8, BDCR_REG)
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7RS_CLOCK_H_ */