This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new cffaf366b0b arch/arm/stm32h7: Cleanup stm32h7rsxx RCC code
cffaf366b0b is described below
commit cffaf366b0b78b469b2d210e87974042571892e7
Author: Peter Barada <[email protected]>
AuthorDate: Mon Nov 2 20:21:00 2026 -0500
arch/arm/stm32h7: Cleanup stm32h7rsxx RCC code
Fixup RCC code for STM32H7S3L8 boards (stm32h7s8-dk and nucleo-h7s3l8):
- DIVR fields are reserved in RM0477
- Provide macros to convert from prescalers to CPRE, BMPRE, PPRE fields
- Compile-time compute derived frequencies from sources/divisors/prescalers
- Compile-time compute PLL[1-3]RGE fields from PLL refx_ck
- Compile-time validate PLL divisors and bus clock prescalers
- Reserved bits in RCC registers must be kept at reset value
- Only set PLL DIV[P,Q,S,T] fields (and enable dividers) if defined
Signed-off-by Peter Barada <[email protected]>
---
arch/arm/src/stm32h7/hardware/stm32h7rsxx_rcc.h | 31 ++++-
arch/arm/src/stm32h7/stm32h7rsxx_rcc.c | 151 +++++++++++++++++++++--
boards/arm/stm32h7/nucleo-h7s3l8/include/board.h | 138 ++++++++++++++-------
boards/arm/stm32h7/stm32h7s8-dk/include/board.h | 146 ++++++++++++++--------
4 files changed, 354 insertions(+), 112 deletions(-)
diff --git a/arch/arm/src/stm32h7/hardware/stm32h7rsxx_rcc.h
b/arch/arm/src/stm32h7/hardware/stm32h7rsxx_rcc.h
index 29340b878b7..450c56296e6 100644
--- a/arch/arm/src/stm32h7/hardware/stm32h7rsxx_rcc.h
+++ b/arch/arm/src/stm32h7/hardware/stm32h7rsxx_rcc.h
@@ -255,6 +255,7 @@
# define RCC_CDCFGR_CPRE_SYSCLKd128 (13 << RCC_CDCFGR_CPRE_SHIFT)
# define RCC_CDCFGR_CPRE_SYSCLKd256 (14 << RCC_CDCFGR_CPRE_SHIFT)
# define RCC_CDCFGR_CPRE_SYSCLKd512 (15 << RCC_CDCFGR_CPRE_SHIFT)
+# define RCC_CDCFGR_CPRE(n) ((LOG2_FLOOR(n) + 7) <<
RCC_CDCFGR_CPRE_SHIFT)
#define RCC_BMCFGR_BMPRE_SHIFT (0) /* AHB clock prescaler */
#define RCC_BMCFGR_BMPRE_MASK (15 << RCC_BMCFGR_BMPRE_SHIFT)
@@ -265,8 +266,9 @@
# define RCC_BMCFGR_BMPRE_SYSCLKd16 (11 << RCC_BMCFGR_BMPRE_SHIFT)
# define RCC_BMCFGR_BMPRE_SYSCLKd64 (12 << RCC_BMCFGR_BMPRE_SHIFT)
# define RCC_BMCFGR_BMPRE_SYSCLKd128 (13 << RCC_BMCFGR_BMPRE_SHIFT)
-# define RCC_BMCFGR_BMPRE_SYSCLKd256 (14 << RCC_BMCFGR_BMPRE_SHIFT)#
define RCC_BMCFGR_BMPRE_SYSCLKd512 (15 << RCC_BMCFGR_BMPRE_SHIFT)
-
+# define RCC_BMCFGR_BMPRE_SYSCLKd256 (14 << RCC_BMCFGR_BMPRE_SHIFT)
+# define RCC_BMCFGR_BMPRE_SYSCLKd512 (15 << RCC_BMCFGR_BMPRE_SHIFT)
+# define RCC_BMCFGR_BMPRE(n) ((LOG2_FLOOR(n) + 7) <<
RCC_BMCFGR_BMPRE_SHIFT)
#define RCC_APBCFGR_PPRE1_SHIFT (0) /* APB1 clock prescaler */
#define RCC_APBCFGR_PPRE1_MASK (7 << RCC_APBCFGR_PPRE1_SHIFT)
# define RCC_APBCFGR_PPRE1_HCLK (0 << RCC_APBCFGR_PPRE1_SHIFT)
@@ -274,6 +276,7 @@
# define RCC_APBCFGR_PPRE1_HCLKd4 (5 << RCC_APBCFGR_PPRE1_SHIFT)
# define RCC_APBCFGR_PPRE1_HCLKd8 (6 << RCC_APBCFGR_PPRE1_SHIFT)
# define RCC_APBCFGR_PPRE1_HCLKd16 (7 << RCC_APBCFGR_PPRE1_SHIFT)
+# define RCC_APBCFGR_PPRE1(n) ((LOG2_FLOOR(n) + 3) <<
RCC_APBCFGR_PPRE1_SHIFT)
#define RCC_APBCFGR_PPRE2_SHIFT (4) /* APB2 clock prescaler */
#define RCC_APBCFGR_PPRE2_MASK (7 << RCC_APBCFGR_PPRE2_SHIFT)
# define RCC_APBCFGR_PPRE2_HCLK (0 << RCC_APBCFGR_PPRE2_SHIFT)
@@ -281,6 +284,7 @@
# define RCC_APBCFGR_PPRE2_HCLKd4 (5 << RCC_APBCFGR_PPRE2_SHIFT)
# define RCC_APBCFGR_PPRE2_HCLKd8 (6 << RCC_APBCFGR_PPRE2_SHIFT)
# define RCC_APBCFGR_PPRE2_HCLKd16 (7 << RCC_APBCFGR_PPRE2_SHIFT)
+# define RCC_APBCFGR_PPRE2(n) ((LOG2_FLOOR(n) + 3) <<
RCC_APBCFGR_PPRE2_SHIFT)
#define RCC_APBCFGR_PPRE4_SHIFT (8) /* APB4 clock prescaler */
#define RCC_APBCFGR_PPRE4_MASK (7 << RCC_APBCFGR_PPRE4_SHIFT)
# define RCC_APBCFGR_PPRE4_HCLK (0 << RCC_APBCFGR_PPRE4_SHIFT)
@@ -288,6 +292,7 @@
# define RCC_APBCFGR_PPRE4_HCLKd4 (5 << RCC_APBCFGR_PPRE4_SHIFT)
# define RCC_APBCFGR_PPRE4_HCLKd8 (6 << RCC_APBCFGR_PPRE4_SHIFT)
# define RCC_APBCFGR_PPRE4_HCLKd16 (7 << RCC_APBCFGR_PPRE4_SHIFT)
+# define RCC_APBCFGR_PPRE4(n) ((LOG2_FLOOR(n) + 3) <<
RCC_APBCFGR_PPRE4_SHIFT)
#define RCC_APBCFGR_PPRE5_SHIFT (12) /* APB5 clock prescaler */
#define RCC_APBCFGR_PPRE5_MASK (7 << RCC_APBCFGR_PPRE5_SHIFT)
# define RCC_APBCFGR_PPRE5_HCLK (0 << RCC_APBCFGR_PPRE5_SHIFT)
@@ -295,6 +300,7 @@
# define RCC_APBCFGR_PPRE5_HCLKd4 (5 << RCC_APBCFGR_PPRE5_SHIFT)
# define RCC_APBCFGR_PPRE5_HCLKd8 (6 << RCC_APBCFGR_PPRE5_SHIFT)
# define RCC_APBCFGR_PPRE5_HCLKd16 (7 << RCC_APBCFGR_PPRE5_SHIFT)
+# define RCC_APBCFGR_PPRE5(n) ((LOG2_FLOOR(n) + 3) <<
RCC_APBCFGR_PPRE5_SHIFT)
/* PLL registers ************************************************************/
@@ -311,6 +317,9 @@
# define RCC_PLLCKSELR_DIVM1(n) RCC_PLLCKSELR_DIVM(n,
RCC_PLLCKSELR_DIVM1_SHIFT)
# define RCC_PLLCKSELR_DIVM2(n) RCC_PLLCKSELR_DIVM(n,
RCC_PLLCKSELR_DIVM2_SHIFT)
# define RCC_PLLCKSELR_DIVM3(n) RCC_PLLCKSELR_DIVM(n,
RCC_PLLCKSELR_DIVM3_SHIFT)
+#define RCC_PLLCKSELR_DIVM1_MASK
RCC_PLLCKSELR_DIVM_MASK(RCC_PLLCKSELR_DIVM1_SHIFT)
+#define RCC_PLLCKSELR_DIVM2_MASK
RCC_PLLCKSELR_DIVM_MASK(RCC_PLLCKSELR_DIVM2_SHIFT)
+#define RCC_PLLCKSELR_DIVM3_MASK
RCC_PLLCKSELR_DIVM_MASK(RCC_PLLCKSELR_DIVM3_SHIFT)
#define RCC_PLLCFGR_PLL1FRACEN (1 << 0) /* PLL1 fractional enable */
#define RCC_PLLCFGR_PLL1VCOSEL (1 << 1) /* PLL1 VCO selection */
@@ -330,6 +339,10 @@
#define RCC_PLLCFGR_PLL2SSCGEN (1 << 13)
#define RCC_PLLCFGR_PLL2RGE_SHIFT (14) /* PLL2 input freq range */
#define RCC_PLLCFGR_PLL2RGE_MASK (3 << RCC_PLLCFGR_PLL2RGE_SHIFT)
+# define RCC_PLLCFGR_PLL2RGE_1_2 (0 << RCC_PLLCFGR_PLL2RGE_SHIFT)
+# define RCC_PLLCFGR_PLL2RGE_2_4 (1 << RCC_PLLCFGR_PLL2RGE_SHIFT)
+# define RCC_PLLCFGR_PLL2RGE_4_8 (2 << RCC_PLLCFGR_PLL2RGE_SHIFT)
+# define RCC_PLLCFGR_PLL2RGE_8_16 (3 << RCC_PLLCFGR_PLL2RGE_SHIFT)
#define RCC_PLLCFGR_PLL2PEN (1 << 16) /* PLL2 P output enable */
#define RCC_PLLCFGR_PLL2QEN (1 << 17) /* PLL2 Q output enable */
#define RCC_PLLCFGR_PLL2REN (1 << 18) /* PLL2 R output enable */
@@ -340,19 +353,33 @@
#define RCC_PLLCFGR_PLL3SSCGEN (1 << 24)
#define RCC_PLLCFGR_PLL3RGE_SHIFT (25) /* PLL3 input freq range */
#define RCC_PLLCFGR_PLL3RGE_MASK (3 << RCC_PLLCFGR_PLL3RGE_SHIFT)
+# define RCC_PLLCFGR_PLL3RGE_1_2 (0 << RCC_PLLCFGR_PLL3RGE_SHIFT)
+# define RCC_PLLCFGR_PLL3RGE_2_4 (1 << RCC_PLLCFGR_PLL3RGE_SHIFT)
+# define RCC_PLLCFGR_PLL3RGE_4_8 (2 << RCC_PLLCFGR_PLL3RGE_SHIFT)
+# define RCC_PLLCFGR_PLL3RGE_8_16 (3 << RCC_PLLCFGR_PLL3RGE_SHIFT)
#define RCC_PLLCFGR_PLL3PEN (1 << 27) /* PLL3 P output enable */
#define RCC_PLLCFGR_PLL3QEN (1 << 28) /* PLL3 Q output enable */
#define RCC_PLLCFGR_PLL3REN (1 << 29) /* PLL3 R output enable */
#define RCC_PLLCFGR_PLL3SEN (1 << 30) /* PLL3 S output enable */
#define RCC_PLLDIVR_DIVN_SHIFT (0) /* PLL N multiplier */
+#define RCC_PLLDIVR_DIVN_MASK (0x1ff << RCC_PLLDIVR_DIVN_SHIFT)
#define RCC_PLLDIVR_DIVP_SHIFT (9) /* PLL P divider */
+#define RCC_PLLDIVR_DIVP_MASK (0x7f << RCC_PLLDIVR_DIVP_SHIFT)
#define RCC_PLLDIVR_DIVQ_SHIFT (16) /* PLL Q divider */
+#define RCC_PLLDIVR_DIVQ_MASK (0x7f << RCC_PLLDIVR_DIVQ_SHIFT)
#define RCC_PLLDIVR_DIVR_SHIFT (24) /* PLL R divider */
+#define RCC_PLLDIVR_DIVR_MASK (0x7f << RCC_PLLDIVR_DIVR_SHIFT)
+#define RCC_PLLDIVR_DIVS_SHIFT (0) /* PLL S divider */
+#define RCC_PLLDIVR_DIVS_MASK (0x7 << RCC_PLLDIVR_DIVS_SHIFT)
+#define RCC_PLLDIVR_DIVT_SHIFT (8) /* PLL T divider */
+#define RCC_PLLDIVR_DIVT_MASK (0x7 << RCC_PLLDIVR_DIVT_SHIFT)
# define RCC_PLLDIVR_DIVN(n) (((n) - 1) << RCC_PLLDIVR_DIVN_SHIFT)
# define RCC_PLLDIVR_DIVP(n) (((n) - 1) << RCC_PLLDIVR_DIVP_SHIFT)
# define RCC_PLLDIVR_DIVQ(n) (((n) - 1) << RCC_PLLDIVR_DIVQ_SHIFT)
# define RCC_PLLDIVR_DIVR(n) (((n) - 1) << RCC_PLLDIVR_DIVR_SHIFT)
+# define RCC_PLLDIVR_DIVS(n) (((n) - 1) << RCC_PLLDIVR_DIVS_SHIFT)
+# define RCC_PLLDIVR_DIVT(n) (((n) - 1) << RCC_PLLDIVR_DIVT_SHIFT)
#define RCC_PLL1DIVR1_N(n) RCC_PLLDIVR_DIVN(n)
#define RCC_PLL1DIVR1_P(n) RCC_PLLDIVR_DIVP(n)
#define RCC_PLL1DIVR1_Q(n) RCC_PLLDIVR_DIVQ(n)
diff --git a/arch/arm/src/stm32h7/stm32h7rsxx_rcc.c
b/arch/arm/src/stm32h7/stm32h7rsxx_rcc.c
index 9df6e4dbb28..a49b7e5f4c0 100644
--- a/arch/arm/src/stm32h7/stm32h7rsxx_rcc.c
+++ b/arch/arm/src/stm32h7/stm32h7rsxx_rcc.c
@@ -61,6 +61,47 @@
# define STM32_PWR_CSR2_SELECTION PWR_CSR2_LDOEN
#endif
+/* Validate CPRE and BMPRE divisors. They must
+ * be defined and a power of two between 1 and 512
+ */
+
+#if (!defined(STM32_CPRE_DIV_VAL) || (STM32_CPRE_DIV_VAL < 1) \
+ || (STM32_CPRE_DIV_VAL > 512) || !IS_POWER_OF_2(STM32_CPRE_DIV_VAL))
+#error "STM32_CPRE_DIV_VAL is not defined or illegal"
+#endif
+#if (!defined(STM32_BMPRE_DIV_VAL) || (STM32_BMPRE_DIV_VAL < 1) \
+ || (STM32_CPRE_DIV_VAL > 512) || !IS_POWER_OF_2(STM32_BMPRE_DIV_VAL))
+#error "STM32_BMPRE_DIV_VAL is not defined or illegal"
+#endif
+
+/* Validate PPRE1, PPRE2, PPRE4, and PPRE5 divisors. If defined
+ * they must be a power of two between 1 and 16.
+ */
+
+#if defined(STM32_PPRE1_DIV_VAL) \
+ && ((STM32_PPRE1_DIV_VAL < 1) || (STM32_PPRE1_DIV_VAL > 16) \
+ || !IS_POWER_OF_2(STM32_PPRE1_DIV_VAL))
+#error "STM32_PPRE1_DIV_VAL is illegal"
+#endif
+
+#if defined(STM32_PPRE2_DIV_VAL) \
+ && ((STM32_PPRE2_DIV_VAL < 1) || (STM32_PPRE2_DIV_VAL > 16) \
+ || !IS_POWER_OF_2(STM32_PPRE2_DIV_VAL))
+#error "STM32_PPRE2_DIV_VAL is illegal"
+#endif
+
+#if defined(STM32_PPRE4_DIV_VAL) \
+ && ((STM32_PPRE4_DIV_VAL < 1) || (STM32_PPRE4_DIV_VAL > 16) \
+ || !IS_POWER_OF_2(STM32_PPRE4_DIV_VAL))
+#error "STM32_PPRE4_DIV_VAL is illegal"
+#endif
+
+#if defined(STM32_PPRE5_DIV_VAL) \
+ && ((STM32_PPRE5_DIV_VAL < 1) || (STM32_PPRE5_DIV_VAL > 16) \
+ || !IS_POWER_OF_2(STM32_PPRE5_DIV_VAL))
+#error "STM32_PPRE5_DIV_VAL is illegal"
+#endif
+
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -445,6 +486,9 @@ static inline void rcc_enableperipherals(void)
void stm32_stdclockconfig(void)
{
uint32_t regval;
+ uint32_t regval_pllcfgr;
+ uint32_t regval_pllxdivr1;
+ uint32_t regval_pllxdivr2;
volatile int32_t timeout;
/* Select the PMU supply the board uses. As on the other H7 parts the low
@@ -554,14 +598,66 @@ void stm32_stdclockconfig(void)
{
}
+ regval_pllcfgr = getreg32(STM32_RCC_PLLCFGR);
+ regval_pllcfgr &= ~(RCC_PLLCFGR_PLL1SEN | RCC_PLLCFGR_PLL1QEN
+ | RCC_PLLCFGR_PLL1PEN | RCC_PLLCFGR_PLL1RGE_MASK
+ | RCC_PLLCFGR_PLL1SSCGEN | RCC_PLLCFGR_PLL1VCOSEL
+ | RCC_PLLCFGR_PLL1FRACEN);
+
+ regval_pllxdivr1 = getreg32(STM32_RCC_PLL1DIVR1);
+ regval_pllxdivr1 &= ~(RCC_PLLDIVR_DIVQ_MASK | RCC_PLLDIVR_DIVP_MASK
+ | RCC_PLLDIVR_DIVN_MASK);
+ regval_pllxdivr2 = getreg32(STM32_RCC_PLL1DIVR2);
+ regval_pllxdivr2 &= ~RCC_PLL1DIVR2_DIVS_MASK;
+
/* Configure PLL1 source, dividers and outputs */
- putreg32(STM32_PLLCFG_PLLSRC | STM32_PLLCFG_PLL1M,
- STM32_RCC_PLLCKSELR);
- putreg32(STM32_PLLCFG_PLL1CFG, STM32_RCC_PLLCFGR);
- putreg32(STM32_PLLCFG_PLL1N | STM32_PLLCFG_PLL1P |
- STM32_PLLCFG_PLL1Q | STM32_PLLCFG_PLL1R,
- STM32_RCC_PLL1DIVR1);
+ /* Determine PLLCFGR:PLL1RGE from ref1_ck */
+#if (STM32_REF1_CK_FREQUENCY >= 1000000 && STM32_REF1_CK_FREQUENCY < 2000000)
+ regval_pllcfgr |= RCC_PLLCFGR_PLL1RGE_1_2;
+#elif (STM32_REF1_CK_FREQUENCY >= 2000000 && STM32_REF1_CK_FREQUENCY < 4000000)
+ regval_pllcfgr |= RCC_PLLCFGR_PLL1RGE_2_4;
+#elif (STM32_REF1_CK_FREQUENCY >= 4000000 && STM32_REF1_CK_FREQUENCY < 8000000)
+ regval_pllcfgr |= RCC_PLLCFGR_PLL1RGE_4_8;
+#elif (STM32_REF1_CK_FREQUENCY >= 8000000 && STM32_REF1_CK_FREQUENCY <
16000000)
+ regval_pllcfgr |= RCC_PLLCFGR_PLL1RGE_8_16;
+#else
+#error "ref1_ck is out of range(see 7.5.5 PLL description in TRM)"
+#endif
+
+ /* Set PLL muptiplier */
+
+ regval_pllxdivr1 |= RCC_PLLDIVR_DIVN(STM32_PLL1_DIVN_VAL);
+
+ /* PLL divisors are enabled IFF divisor value is defined */
+
+#ifdef STM32_PLL1_DIVP_VAL
+ regval_pllcfgr |= RCC_PLLCFGR_PLL1PEN;
+ regval_pllxdivr1 |= RCC_PLLDIVR_DIVP(STM32_PLL1_DIVP_VAL);
+#endif
+#ifdef STM32_PLL1_DIVQ_VAL
+ regval_pllcfgr |= RCC_PLLCFGR_PLL1QEN;
+ regval_pllxdivr1 |= RCC_PLLDIVR_DIVQ(STM32_PLL1_DIVQ_VAL);
+#endif
+#ifdef STM32_PLL1_DIVS_VAL
+ regval_pllcfgr |= RCC_PLLCFGR_PLL1SEN;
+ regval_pllxdivr2 |= RCC_PLLDIVR_DIVS(STM32_PLL1_DIVS_VAL);
+#endif
+
+ /* Set PLL source clock, as well as DIVM1 */
+
+ regval = getreg32(STM32_RCC_PLLCKSELR);
+ regval &= ~(RCC_PLLCKSELR_DIVM1_MASK | RCC_PLLCKSELR_PLLSRC_MASK);
+ regval |= STM32_PLLCFG_PLLSRC | RCC_PLLCKSELR_DIVM1(STM32_PLL1_DIVM_VAL);
+ putreg32(regval, STM32_RCC_PLLCKSELR);
+
+ /* Set RCC_PLLCFGR, RCC_PLL1DIVR1, RCC_PLL1DIVR2 */
+
+ putreg32(regval_pllcfgr, STM32_RCC_PLLCFGR);
+ putreg32(regval_pllxdivr1, STM32_RCC_PLL1DIVR1);
+ putreg32(regval_pllxdivr2, STM32_RCC_PLL1DIVR2);
+
+ /* Enable PLL1 and wait for it to become ready */
modifyreg32(STM32_RCC_CR, 0, RCC_CR_PLL1ON);
while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL1RDY) == 0)
@@ -570,18 +666,49 @@ void stm32_stdclockconfig(void)
/* Configure the CPU, bus matrix and APB prescalers */
- putreg32(STM32_RCC_CDCFGR_CPRE, STM32_RCC_CDCFGR);
- putreg32(STM32_RCC_BMCFGR_BMPRE, STM32_RCC_BMCFGR);
- putreg32(STM32_RCC_APBCFGR_PPRE1 | STM32_RCC_APBCFGR_PPRE2 |
- STM32_RCC_APBCFGR_PPRE4 | STM32_RCC_APBCFGR_PPRE5,
- STM32_RCC_APBCFGR);
+ regval = getreg32(STM32_RCC_CDCFGR);
+ regval &= ~RCC_CDCFGR_CPRE_MASK;
+
+ /* Map from CRPE divisor to RCC_CDCFGR:CPRE field value */
+
+ regval |= RCC_CDCFGR_CPRE(STM32_CPRE_DIV_VAL);
+
+ putreg32(regval, STM32_RCC_CDCFGR);
+ regval = getreg32(STM32_RCC_BMCFGR);
+
+ /* Map from BMPRE divisor to RCC_BMCFGR:BMPRE field value */
+
+ regval |= RCC_BMCFGR_BMPRE(STM32_BMPRE_DIV_VAL);
+
+ putreg32(regval, STM32_RCC_BMCFGR);
+
+ regval = getreg32(STM32_RCC_APBCFGR);
+
+ /* Map from PPRE[1-5] divisor to RCC_APBCFGR:PPRE[1-5] field value */
+
+#if defined(STM32_PPRE1_DIV_VAL)
+ regval |= RCC_APBCFGR_PPRE1(STM32_PPRE1_DIV_VAL);
+#endif
+#if defined(STM32_PPRE2_DIV_VAL)
+ regval |= RCC_APBCFGR_PPRE1(STM32_PPRE2_DIV_VAL);
+#endif
+#if defined(STM32_PPRE4_DIV_VAL)
+ regval |= RCC_APBCFGR_PPRE1(STM32_PPRE4_DIV_VAL);
+#endif
+#if defined(STM32_PPRE5_DIV_VAL)
+ regval |= RCC_APBCFGR_PPRE1(STM32_PPRE5_DIV_VAL);
+#endif
+ putreg32(regval, STM32_RCC_APBCFGR);
/* Select PLL1P as the system clock source */
regval = getreg32(STM32_RCC_CFGR);
regval &= ~RCC_CFGR_SW_MASK;
- regval |= RCC_CFGR_SW_PLL1;
+ regval |= STM32_SYS_CK_SWCFG;
putreg32(regval, STM32_RCC_CFGR);
+
+ /* Wait for the system clock switch to take effect */
+
while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) !=
RCC_CFGR_SWS_PLL1)
{
diff --git a/boards/arm/stm32h7/nucleo-h7s3l8/include/board.h
b/boards/arm/stm32h7/nucleo-h7s3l8/include/board.h
index 4330eb33f22..87e3b12b387 100644
--- a/boards/arm/stm32h7/nucleo-h7s3l8/include/board.h
+++ b/boards/arm/stm32h7/nucleo-h7s3l8/include/board.h
@@ -41,6 +41,14 @@
/* Clocking *****************************************************************/
+/* Refer to following figures in ST RM0477 to understand clock
+ * naming and routing:
+ *
+ * page 354: Figure 40. Top-level clock tree
+ * page 371: Figure 48. Pll block diagram
+ * page 378: Figure 51. Core and bus generation
+ */
+
/* The NUCLEO-H7S3L8 board provides the following clock sources:
*
* MCO: 24 MHz from the ST-LINK is available as the HSE input
@@ -57,72 +65,109 @@
#define STM32_LSI_FREQUENCY 32000ul
#define STM32_LSE_FREQUENCY 32768ul
-/* Main PLL configuration
- *
- * The HSI and HSE configurations both produce a 600 MHz PLL1 VCO and use
- * PLL1P as the system clock:
+/* PLL clocking is derived from pll_ck in put source divided by
+ * PLL DIVM divisor then multiplied by DIVM divisor:
*
- * HSI: PLL1_VCO = (64 MHz / 32) * 300 = 600 MHz
- * HSE: PLL1_VCO = (24 MHz / 2) * 50 = 600 MHz
- *
- * PLL1P = 600 MHz
- * PLL1Q = 300 MHz
- * PLL1R = 300 MHz
+ * VCOx = (pll_ck / DIVNx) * DIVMx
*/
-#ifdef CONFIG_NUCLEO_H7S3L8_USE_HSE
+/* Define pll_ck clock source and frequency */
+
+#ifdef CONFIG_STM32H7S8_DK_USE_HSE
# define STM32_BOARD_USEHSE
# define STM32_HSEBYP_ENABLE
# define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE
-# define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(2)
-# define STM32_PLLCFG_PLL1N RCC_PLL1DIVR1_N(50)
-# define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1RGE_8_16 | \
- RCC_PLLCFGR_PLL1PEN | \
- RCC_PLLCFGR_PLL1QEN | \
- RCC_PLLCFGR_PLL1REN)
+# define STM32_PLL_CK_FREQUENCY STM32_HSE_FREQUENCY
#else
# define STM32_BOARD_USEHSI
# define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSI
-# define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(32)
-# define STM32_PLLCFG_PLL1N RCC_PLL1DIVR1_N(300)
-# define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1RGE_2_4 | \
- RCC_PLLCFGR_PLL1PEN | \
- RCC_PLLCFGR_PLL1QEN | \
- RCC_PLLCFGR_PLL1REN)
+# define STM32_PLL_CK_FREQUENCY STM32_HSI_FREQUENCY
#endif
-#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR1_P(1)
-#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR1_Q(2)
-#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR1_R(2)
+/* Main PLL configuration (PLL1)
+ *
+ * The HSI and HSE configurations can both generate a 600 MHz
+ * PLL1 VCO clock to use as the system clock:
+ *
+ * HSE: PLL1_VCO = (24 MHz / 2) * 50 = 600 MHz
+ * HSI: PLL1_VCO = (64 MHz / 32) * 300 = 600 MHz
+ */
+
+#ifdef CONFIG_STM32H7S8_DK_USE_HSE
+#define STM32_PLL1_DIVM_VAL 2
+#define STM32_PLL1_DIVN_VAL 50
+#else
+#define STM32_PLL1_DIVM_VAL 32
+#define STM32_PLL1_DIVN_VAL 300
+#endif
-#define STM32_VCO1_FREQUENCY 600000000ul
-#define STM32_PLL1P_FREQUENCY STM32_VCO1_FREQUENCY
-#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 2)
-#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 2)
+#define STM32_REF1_CK_FREQUENCY (STM32_PLL_CK_FREQUENCY / STM32_PLL1_DIVM_VAL)
+#define STM32_VCO1_CK_FREQUENCY (STM32_REF1_CK_FREQUENCY *
STM32_PLL1_DIVN_VAL)
-/* SYSCLK = PLL1P = 600 MHz
- * CPUCLK = SYSCLK
+/* Define main PLL1 output dividers:
+ *
+ * pll1_p_ck = (vco1_ck / 1) => 600Mhz
+ * pll1_q_ck = (vco1_ck / 2) => 300Mhz
+ * pll1_s_ck = (vco1_ck / 2) => 300Mhz
+ */
+
+#define STM32_PLL1_DIVP_VAL 1
+#define STM32_PLL1P_FREQUENCY (STM32_VCO1_CK_FREQUENCY/STM32_PLL1_DIVP_VAL)
+#define STM32_PLL1_DIVQ_VAL 2
+#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_CK_FREQUENCY/STM32_PLL1_DIVQ_VAL)
+#define STM32_PLL1_DIVS_VAL 2
+#define STM32_PLL1S_FREQUENCY (STM32_VCO1_CK_FREQUENCY/STM32_PLL1_DIVS_VAL)
+
+/* SW field of SW selects which clock source to use as sys_ck;
+ * use 600 Mhz pll1_p_ck
+ */
+
+#define STM32_SYS_CK_SWCFG RCC_CFGR_SW_PLL1
+#define STM32_SYS_CK_FREQUENCY STM32_PLL1P_FREQUENCY
+
+/* CPRE is divisor of sys_ck to generate sys_cpu_ck:
+ *
+ * sys_cpu_ck = PLL1P / CPRE = PLL1P / 1 = 600 MHz
+ * SYSCLK = sys_cpu_ck
+ * CPUCLK = sys_cpu_ck
*/
-#define STM32_RCC_CDCFGR_CPRE RCC_CDCFGR_CPRE_SYSCLK
-#define STM32_SYSCLK_FREQUENCY STM32_PLL1P_FREQUENCY
+#define STM32_CPRE_DIV_VAL 1
+#define STM32_SYSCLK_FREQUENCY (STM32_SYS_CK_FREQUENCY / STM32_CPRE_DIV_VAL)
#define STM32_CPUCLK_FREQUENCY STM32_SYSCLK_FREQUENCY
-/* AHB clock (HCLK) is SYSCLK/2 (300 MHz). */
+/* BMPRE is divisor of sys_cpu_ck to generate sys_bus_clock (AHB clock):
+ *
+ * sys_bus_ck = SYSCLK / 2 = 600 / 2 = 300 Mhz
+ * HCLK = sys_bus_ck
+ */
+
+#define STM32_BMPRE_DIV_VAL 2
+#define STM32_HCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / STM32_BMPRE_DIV_VAL)
+
+/* APB1, APB2, APB4 and APB5 peripheral clocks are HCLK/2 (150 MHz):
+ *
+ * rcc_pclk1 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK1 = rcc_pclk1
+ * rcc_pclk2 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK2 = rcc_pclk2
+ * rcc_pclk4 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK4 = rcc_pclk4
+ * rcc_pclk5 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK5 = rcc_pclk5
+ */
+
+#define STM32_PPRE1_DIV_VAL 2
+#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
-#define STM32_RCC_BMCFGR_BMPRE RCC_BMCFGR_BMPRE_SYSCLKd2
-#define STM32_HCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 2)
+#define STM32_PPRE2_DIV_VAL 2
+#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
-/* APB1, APB2, APB4 and APB5 clocks are HCLK/2 (150 MHz). */
+#define STM32_PPRE4_DIV_VAL 2
+#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
-#define STM32_RCC_APBCFGR_PPRE1 RCC_APBCFGR_PPRE1_HCLKd2
-#define STM32_RCC_APBCFGR_PPRE2 RCC_APBCFGR_PPRE2_HCLKd2
-#define STM32_RCC_APBCFGR_PPRE4 RCC_APBCFGR_PPRE4_HCLKd2
-#define STM32_RCC_APBCFGR_PPRE5 RCC_APBCFGR_PPRE5_HCLKd2
-#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
-#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
-#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
-#define STM32_PCLK5_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
+#define STM32_PPRE5_DIV_VAL 2
+#define STM32_PCLK5_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
/* Timers on APB1 and APB2 are clocked at twice the peripheral clock. */
@@ -137,7 +182,6 @@
#define STM32_TIM14_CLKIN (2 * STM32_PCLK1_FREQUENCY)
#define STM32_TIM1_CLKIN (2 * STM32_PCLK2_FREQUENCY)
-#define STM32_TIM8_CLKIN (2 * STM32_PCLK2_FREQUENCY)
#define STM32_TIM9_CLKIN (2 * STM32_PCLK2_FREQUENCY)
#define STM32_TIM15_CLKIN (2 * STM32_PCLK2_FREQUENCY)
#define STM32_TIM16_CLKIN (2 * STM32_PCLK2_FREQUENCY)
diff --git a/boards/arm/stm32h7/stm32h7s8-dk/include/board.h
b/boards/arm/stm32h7/stm32h7s8-dk/include/board.h
index d5dac67356e..f180435c535 100644
--- a/boards/arm/stm32h7/stm32h7s8-dk/include/board.h
+++ b/boards/arm/stm32h7/stm32h7s8-dk/include/board.h
@@ -41,14 +41,21 @@
/* Clocking *****************************************************************/
+/* Refer to following figures in ST RM0477 to understand clock
+ * naming and routing:
+ *
+ * page 354: Figure 40. Top-level clock tree
+ * page 371: Figure 48. Pll block diagram
+ * page 378: Figure 51. Core and bus generation
+ */
+
/* The STM32H7S8-DK board provides the following clock sources:
*
- * MCO: 24 MHz from the ST-LINK is available as the HSE input
- * X2: 32.768 kHz crystal for LSE
+ * X3: 24 MHz X3 connect to HSE OSC-IN
+ * X2: 32.768 kHz X2 crystal for LSE
*
- * HSI is selected by default so that the board can run when the ST-LINK is
- * not supplying its MCO clock. CONFIG_STM32H7S8_DK_USE_HSE selects the
- * 24 MHz bypass clock instead.
+ * HSI is selected by default. CONFIG_STM32H7S8_DK_USE_HSE selects the
+ * 24 MHz HSE clock instead.
*/
#define STM32_BOARD_XTAL 24000000ul
@@ -57,72 +64,109 @@
#define STM32_LSI_FREQUENCY 32000ul
#define STM32_LSE_FREQUENCY 32768ul
-/* Main PLL configuration
- *
- * The HSI and HSE configurations both produce a 600 MHz PLL1 VCO and use
- * PLL1P as the system clock:
+/* PLL clocking is derived from pll_ck in put source divided by
+ * PLL DIVM divisor then multiplied by DIVM divisor:
*
- * HSI: PLL1_VCO = (64 MHz / 32) * 300 = 600 MHz
- * HSE: PLL1_VCO = (24 MHz / 2) * 50 = 600 MHz
- *
- * PLL1P = 600 MHz
- * PLL1Q = 300 MHz
- * PLL1R = 300 MHz
+ * VCOx = (pll_ck / DIVNx) * DIVMx
*/
+/* Define pll_ck clock source and frequency */
+
#ifdef CONFIG_STM32H7S8_DK_USE_HSE
# define STM32_BOARD_USEHSE
# define STM32_HSEBYP_ENABLE
# define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE
-# define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(2)
-# define STM32_PLLCFG_PLL1N RCC_PLL1DIVR1_N(50)
-# define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1RGE_8_16 | \
- RCC_PLLCFGR_PLL1PEN | \
- RCC_PLLCFGR_PLL1QEN | \
- RCC_PLLCFGR_PLL1REN)
+# define STM32_PLL_CK_FREQUENCY STM32_HSE_FREQUENCY
#else
# define STM32_BOARD_USEHSI
# define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSI
-# define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(32)
-# define STM32_PLLCFG_PLL1N RCC_PLL1DIVR1_N(300)
-# define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1RGE_2_4 | \
- RCC_PLLCFGR_PLL1PEN | \
- RCC_PLLCFGR_PLL1QEN | \
- RCC_PLLCFGR_PLL1REN)
+# define STM32_PLL_CK_FREQUENCY STM32_HSI_FREQUENCY
+#endif
+
+/* Main PLL configuration (PLL1)
+ *
+ * The HSI and HSE configurations can both generate a 600 MHz
+ * PLL1 VCO clock to use as the system clock:
+ *
+ * HSE: PLL1_VCO = (24 MHz / 2) * 50 = 600 MHz
+ * HSI: PLL1_VCO = (64 MHz / 32) * 300 = 600 MHz
+ */
+
+#ifdef CONFIG_STM32H7S8_DK_USE_HSE
+#define STM32_PLL1_DIVM_VAL 2
+#define STM32_PLL1_DIVN_VAL 50
+#else
+#define STM32_PLL1_DIVM_VAL 32
+#define STM32_PLL1_DIVN_VAL 300
#endif
-#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR1_P(1)
-#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR1_Q(2)
-#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR1_R(2)
+#define STM32_REF1_CK_FREQUENCY (STM32_PLL_CK_FREQUENCY / STM32_PLL1_DIVM_VAL)
+#define STM32_VCO1_CK_FREQUENCY (STM32_REF1_CK_FREQUENCY *
STM32_PLL1_DIVN_VAL)
+
+/* Define main PLL1 output dividers:
+ *
+ * pll1_p_ck = (vco1_ck / 1) => 600Mhz
+ * pll1_q_ck = (vco1_ck / 2) => 300Mhz
+ * pll1_s_ck = (vco1_ck / 2) => 300Mhz
+ */
+
+#define STM32_PLL1_DIVP_VAL 1
+#define STM32_PLL1P_FREQUENCY (STM32_VCO1_CK_FREQUENCY/STM32_PLL1_DIVP_VAL)
+#define STM32_PLL1_DIVQ_VAL 2
+#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_CK_FREQUENCY/STM32_PLL1_DIVQ_VAL)
+#define STM32_PLL1_DIVS_VAL 2
+#define STM32_PLL1S_FREQUENCY (STM32_VCO1_CK_FREQUENCY/STM32_PLL1_DIVS_VAL)
+
+/* SW field of SW selects which clock source to use as sys_ck;
+ * use 600 Mhz pll1_p_ck
+ */
-#define STM32_VCO1_FREQUENCY 600000000ul
-#define STM32_PLL1P_FREQUENCY STM32_VCO1_FREQUENCY
-#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 2)
-#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 2)
+#define STM32_SYS_CK_SWCFG RCC_CFGR_SW_PLL1
+#define STM32_SYS_CK_FREQUENCY STM32_PLL1P_FREQUENCY
-/* SYSCLK = PLL1P = 600 MHz
- * CPUCLK = SYSCLK
+/* CPRE is divisor of sys_ck to generate sys_cpu_ck:
+ *
+ * sys_cpu_ck = PLL1P / CPRE = PLL1P / 1 = 600 MHz
+ * SYSCLK = sys_cpu_ck
+ * CPUCLK = sys_cpu_ck
*/
-#define STM32_RCC_CDCFGR_CPRE RCC_CDCFGR_CPRE_SYSCLK
-#define STM32_SYSCLK_FREQUENCY STM32_PLL1P_FREQUENCY
+#define STM32_CPRE_DIV_VAL 1
+#define STM32_SYSCLK_FREQUENCY (STM32_SYS_CK_FREQUENCY / STM32_CPRE_DIV_VAL)
#define STM32_CPUCLK_FREQUENCY STM32_SYSCLK_FREQUENCY
-/* AHB clock (HCLK) is SYSCLK/2 (300 MHz). */
+/* BMPRE is divisor of sys_cpu_ck to generate sys_bus_clock (AHB clock):
+ *
+ * sys_bus_ck = SYSCLK / 2 = 600 / 2 = 300 Mhz
+ * HCLK = sys_bus_ck
+ */
+
+#define STM32_BMPRE_DIV_VAL 2
+#define STM32_HCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / STM32_BMPRE_DIV_VAL)
+
+/* APB1, APB2, APB4 and APB5 peripheral clocks are HCLK/2 (150 MHz):
+ *
+ * rcc_pclk1 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK1 = rcc_pclk1
+ * rcc_pclk2 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK2 = rcc_pclk2
+ * rcc_pclk4 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK4 = rcc_pclk4
+ * rcc_pclk5 = sys_bus_ck / 2 = 300 / 2 = 150 Mhz
+ * PCLK5 = rcc_pclk5
+ */
+
+#define STM32_PPRE1_DIV_VAL 2
+#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
-#define STM32_RCC_BMCFGR_BMPRE RCC_BMCFGR_BMPRE_SYSCLKd2
-#define STM32_HCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 2)
+#define STM32_PPRE2_DIV_VAL 2
+#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
-/* APB1, APB2, APB4 and APB5 clocks are HCLK/2 (150 MHz). */
+#define STM32_PPRE4_DIV_VAL 2
+#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
-#define STM32_RCC_APBCFGR_PPRE1 RCC_APBCFGR_PPRE1_HCLKd2
-#define STM32_RCC_APBCFGR_PPRE2 RCC_APBCFGR_PPRE2_HCLKd2
-#define STM32_RCC_APBCFGR_PPRE4 RCC_APBCFGR_PPRE4_HCLKd2
-#define STM32_RCC_APBCFGR_PPRE5 RCC_APBCFGR_PPRE5_HCLKd2
-#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
-#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
-#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
-#define STM32_PCLK5_FREQUENCY (STM32_HCLK_FREQUENCY / 2)
+#define STM32_PPRE5_DIV_VAL 2
+#define STM32_PCLK5_FREQUENCY (STM32_HCLK_FREQUENCY / STM32_PPRE1_DIV_VAL)
/* Timers on APB1 and APB2 are clocked at twice the peripheral clock. */
@@ -137,7 +181,7 @@
#define STM32_TIM14_CLKIN (2 * STM32_PCLK1_FREQUENCY)
#define STM32_TIM1_CLKIN (2 * STM32_PCLK2_FREQUENCY)
-#define STM32_TIM8_CLKIN (2 * STM32_PCLK2_FREQUENCY)
+#define STM32_TIM9_CLKIN (2 * STM32_PCLK2_FREQUENCY)
#define STM32_TIM15_CLKIN (2 * STM32_PCLK2_FREQUENCY)
#define STM32_TIM16_CLKIN (2 * STM32_PCLK2_FREQUENCY)
#define STM32_TIM17_CLKIN (2 * STM32_PCLK2_FREQUENCY)