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)

Reply via email to