Last edited one year ago

STM32MP13 clock tree

Applicable for STM32MP13x lines


All the peripherals receive one or several clocks that are generated via RCC internal peripheral. RCC relies on several clocks sources (LSI, LSE, HSI, HSE, CSI) and four PLL in order to provide adequate input frequencies to all the peripherals. The clock tree covers all the system clock distribution aspects, from the clock sources to the consumer peripherals (internal and external), except clock gating management that is locally controlled by each peripheral driver.

1. Overview[edit source]

The clock tree is managed via RCC internal peripheral hardware block and it is configured at different steps from the Cortex-A7:

  • When the device is reset, all RCC registers take their reset values: the four PLL are disabled and most of the clock source selectors are pointing to the HSI.
  • The ROM Code configures the minimum clock tree needed to boot on the selected boot device.
  • TF-A BL2 has the same strategy as the ROM code, configuring the minimum clock tree needed for its execution, thanks to the configuration given in the device tree.
  • OP-TEE completely configures the clock tree as expected, all the way up to Linux, thanks to the configuration given in the device tree.
  • Linux may partly modify clock tree at runtime thanks to SCMI clock services provided by OP-TEE secure OS. Information related to SCMI are taken from the device tree:

2. How to build a clock tree?[edit source]

Building a clock tree is quite complex as it needs to take into account the constraints set by each internal and external peripheral, including external clock sources.

We encourage the use of STM32CubeMX to build the clock tree, and avoid having to know all internal peripherals details: the tool allows to select the peripherals that will be present on the board, fix the clock sources frequencies and automatically find an optimized clock tree. It is then able to generate the device tree that is directly consumed by the boot chain and the secure OS. Linux kernel will be able to modify clock tree at run time thanks to SCMI clock services provided by OP-TEE.

3. ST boards clock tree[edit source]

This chapter ensures that all peripherals receive clocks with characteristics compatible with the specification (frequency, duty cycle, precision) on each ST board.

Info white.png Information
See How to change the CPU frequency article for more information about the CPU frequency setting (PLL1P), including dynamic voltage and frequency scaling (DVFS) configuration.

3.1. STM32MP135F-DK Discovery kit More info green.png case[edit source]

This chapter shows the result of the boot time clock tree set by the FSBL, overlaid by the run time clock tree set by the Secure OS on STM32MP135F-DK Discovery kit More info green.png.

Linux eventual runtime modifications are not covered here.

3.1.1. Clock tree[edit source]

The following table shows what STM32MP135F-DK Discovery kit More info green.png clock tree looks like, as a result of the boot chain execution with the device tree built with STM32CubeMX.

Component              | Parent  |   Frequency     | Used?  | Comment                           |
-----------------------|---------|-----------------|--------|-----------------------------------|
LSI                    |N.A.     |    0.032000 MHz |  yes   | Mandatory for IWDG, DAC
  IWDG1                |LSI      |    0.032000 MHz |  yes   |
  IWDG2                |LSI      |    0.032000 MHz |  yes   |
LSE                    |N.A.     |    0.032768 MHz |  yes   | Mandatory for DTS
  RTC                  |LSE      |    0.032768 MHz |  yes   |
  TAMP                 |LSE      |    0.032768 MHz |  yes   |
  DTS                  |LSE      |    0.032768 MHz |  yes   |
HSI                    |N.A.     |   64.000000 MHz |  yes   |
  I2C1                 |HSI      |   64.000000 MHz |  yes   | Rpi and peripherals
  I2C2                 |HSI      |   64.000000 MHz |  no    |
  I2C4                 |HSI      |   64.000000 MHz |  yes   | PMIC
  I2C5                 |HSI      |   64.000000 MHz |  yes   | Rpi and peripherals 
  USART1               |HSI      |   64.000000 MHz |  no    | Rpi (not used by default)
  USART2               |HSI      |   64.000000 MHz |  yes   | Bluetooth
  USART3               |HSI      |   64.000000 MHz |  no    |
  UART4                |HSI      |   64.000000 MHz |  yes   | Linux console
  UART5                |HSI      |   64.000000 MHz |  no    |
  USART6               |HSI      |   64.000000 MHz |  no    |
  UART7                |HSI      |   64.000000 MHz |  yes   | Arduino
  UART8                |HSI      |   64.000000 MHz |  no    | Rpi (not used by default)
HSE                    |N.A.     |   24.000000 MHz |  yes   |
  RTCDIV               |HSE      |    1.000000 MHz |  yes   | Only used when RTC source is HSE
  USBPHYC              |HSE      |   24.000000 MHz |  yes   | USB PHY Ctrl for USB Host and OTG
    USBPLL             |USBPHYC  |   48.000000 MHz |  yes   |
      USBO             |USBPLL   |   48.000000 MHz |  yes   | USB OTG
      USBH             |USBPLL   |   48.000000 MHz |  yes   | USB Host
  STGEN                |HSE      |   24.000000 MHz |  yes   |
  FDCAN2               |HSE      |   24.000000 MHz |  no    | Rpi (not used by default)
  ck_per               |HSE      |   24.000000 MHz |  yes   |
    ADC2               |ck_per   |   24.000000 MHz |  yes   | Analog watchdog
  PLL1                 |HSE      |         xxx MHz |  yes   |
    PLL1P              |PLL1     |         xxx MHz |  yes   |
      MPUDIV           |PLL1P    |         xxx MHz |  yes   |
      Cortex-A7        |PLL1P    |         xxx MHz |  yes   | 650 MHz or 1 GHz, see the information box above
  PLL2                 |HSE      |  533.000000 MHz |  yes   |
    PLL2P              |PLL2     |  266.500000 MHz |  yes   |
      AXI              |PLL2P    |  266.500000 MHz |  yes   | 266.5 MHz
        FMC            |AXI      |  266.500000 MHz |  no    |
        QSPI           |AXI      |  266.500000 MHz |  no    |
        SAES           |AXI      |  266.500000 MHz |  yes   |
        TZC            |AXI      |  266.500000 MHz |  yes   |
        SYSRAM         |AXI      |  266.500000 MHz |  yes   |
        ROM            |AXI      |  266.500000 MHz |  yes   |
        AHB5           |AXI      |  266.500000 MHz |  yes   | < 266MHz
          CRYP1        |AHB5     |  266.500000 MHz |  yes   |
          HASH1        |AHB5     |  266.500000 MHz |  yes   |
          BKPSRAM      |AHB5     |  266.500000 MHz |  yes   |
          PKA          |AHB5     |  266.500000 MHz |  yes   |
        AHB6           |AXI      |  266.500000 MHz |  yes   | < 266MHz
          CRC1         |AHB6     |  266.500000 MHz |  yes   |
          MDMA         |AHB6     |  266.500000 MHz |  yes   |
          MCE          |AHB6     |  266.500000 MHz |  yes   |
        APB4           |AXI      |  133.250000 MHz |  yes   | < 133MHz
          GPIOA-I      |APB4     |  133.250000 MHz |  yes   |
        APB5           |AXI      |   66.625000 MHz |  yes   | < 133MHz
          BSEC         |APB5     |   66.625000 MHz |  yes   | < 67MHz
          ETZPC        |APB5     |   66.625000 MHz |  yes   |
        DBGAPB         |AXI      |  133.250000 MHz |  yes   | JTAG & Coresight
          DBGMCU       |DBGAPB   |   66.625000 MHz |  yes   |
    PLL2Q              |PLL2     |  266.500000 MHz |  yes   |
      DCMIPP           |PLL2Q    |  266.500000 MHz |  yes   | < 533MHz
    PLL2R              |PLL2     |  533.000000 MHz |  yes   |
      DDRPHYC          |PLL2R    |  533.000000 MHz |  yes   |
      DDRC             |PLL2R    |  533.000000 MHz |  yes   |
      DDRPERFM         |PLL2R    |  533.000000 MHz |  yes   |
  PLL3                 |HSE      |  417.755859 MHz |  yes   |
    PLL3P              |PLL3     |  208.877930 MHz |  yes   |
      MLAHB            |PLL3P    |  208.877930 MHz |  yes   | < 209MHz
        SRAM1          |MLAHB    |  208.877930 MHz |  yes   |
        SRAM2          |MLAHB    |  208.877930 MHz |  yes   |
        SRAM3          |MLAHB    |  208.877930 MHz |  yes   |
        DFSDM          |MLAHB    |  208.877930 MHz |  no    | Rpi (not used by default)
        AHB1           |MLAHB    |  104.438965 MHz |  yes   | < 104.5MHz
        AHB2           |MLAHB    |  208.877930 MHz |  yes   | < 209MHz
          DMA1         |AHB2     |  208.877930 MHz |  yes   |
          DMA2         |AHB2     |  208.877930 MHz |  yes   |
          DMA3         |AHB2     |  208.877930 MHz |  yes   |
          DMAMUX1      |AHB2     |  208.877930 MHz |  yes   |
          DMAMUX2      |AHB2     |  208.877930 MHz |  yes   |
        APB1           |MLAHB    |  104.438965 MHz |  yes   |
          LPTIM1       |APB1     |  104.438965 MHz |  no    |
        TIMG1          |MLAHB    |  208.877930 MHz |  yes   |
          TIM2         |TIMG1    |  208.877930 MHz |  no    | TIM Group 1
          TIM3         |TIMG1    |  208.877930 MHz |  no    | TIM Group 1 - Rpi (not used by default)
          TIM4         |TIMG1    |  208.877930 MHz |  no    | TIM Group 1 - Rpi (not used by default) 
          TIM5         |TIMG1    |  208.877930 MHz |  no    | TIM Group 1
          TIM6         |TIMG1    |  208.877930 MHz |  no    | TIM Group 1
          TIM7         |TIMG1    |  208.877930 MHz |  no    | TIM Group 1
        TIMG2          |MLAHB    |  208.877930 MHz |  yes   | 
          TIM1         |TIMG2    |  208.877930 MHz |  no    | TIM Group 2
          TIM8         |TIMG2    |  208.877930 MHz |  no    | TIM Group 2 - Rpi (not used by default)
        TIMG3          |MLAHB    |  208.877930 MHz |  yes   | 
          TIM12        |TIMG3    |  208.877930 MHz |  no    | TIM Group 3
          TIM13        |TIMG3    |  208.877930 MHz |  no    | TIM Group 3 
          TIM14        |TIMG3    |  208.877930 MHz |  no    | TIM Group 3 - Rpi (not used by default)
          TIM15        |TIMG3    |  208.877930 MHz |  no    | TIM Group 3
          TIM16        |TIMG3    |  208.877930 MHz |  no    | TIM Group 3
          TIM17        |TIMG3    |  208.877930 MHz |  no    | TIM Group 3
        APB3           |MLAHB    |  104.438965 MHz |  yes   |
          LPTIM2       |APB3     |  104.438965 MHz |  no    |
          LPTIM3       |APB3     |  104.438965 MHz |  yes   |
          LPTIM4       |APB3     |  104.438965 MHz |  no    |
          LPTIM5       |APB3     |  104.438965 MHz |  no    |
          SYSCFG       |APB3     |  104.438965 MHz |  yes   |
          VREFBUF      |APB3     |  104.438965 MHz |  yes   |
          HDP          |APB3     |  104.438965 MHz |  no    |
        APB6           |MLAHB    |  104.438965 MHz |  yes   |
          I2C3         |APB6     |  104.438965 MHz |  no    |
          SPI5         |APB6     |  104.438965 MHz |  no    | Rpi (not used by default)
        AHB4           |MLAHB    |  208.877930 MHz |  yes   | < 209MHz
          PWR          |AHB4     |  208.877930 MHz |  yes   |
          RCC          |AHB4     |  208.877930 MHz |  yes   |
          EXTI         |AHB4     |  208.877930 MHz |  yes   |
    PLL3Q              |PLL3     |   24.573874 MHz |  yes   |
    PLL3R              |PLL3     |   11.290699 MHz |  yes   |
  PLL4                 |HSE      |  600.000000 MHz |  yes   |
    PLL4P              |PLL4     |   50.000000 MHz |  yes   |
      ETH1             |PLL4P    |   50.000000 MHz |  yes   | 50MHz from the SoC
      ETH2             |PLL4P    |   50.000000 MHz |  yes   | 50MHz from the SoC
      SDMMC1           |PLL4P    |   50.000000 MHz |  yes   | µSD card
      SDMMC2           |PLL4P    |   50.000000 MHz |  yes   | Wifi
      SPI1             |PLL4P    |   50.000000 MHz |  no    |
      SPI2             |PLL4P    |   50.000000 MHz |  no    |
      SPI3             |PLL4P    |   50.000000 MHz |  no    |
      SPDIFRX          |PLL4P    |   50.000000 MHz |  no    |
    PLL4Q              |PLL4     |   10.000000 MHz |  yes   |
      LTDC             |PLL4Q    |   10.000000 MHz |  yes   | LTDC display pixel clock
      SAI1             |PLL4Q    |   10.000000 MHz |  no    | Rpi (not used by default)
      SAI2             |PLL4Q    |   10.000000 MHz |  no    |
      SPI4             |PLL4Q    |   10.000000 MHz |  no    |
    PLL4R              |PLL4     |   50.000000 MHz |  yes   |
      ADC1             |PLL4R    |   50.000000 MHz |  no    |
      RNG              |PLL4R    |   50.000000 MHz |  yes   |
CSI                    |N.A.     |    4.000000 MHz |  yes   | Mandatory for IO compensation
-----------------------|---------|-----------------|--------|-----------------------------------|

3.1.2. Device tree[edit source]

As mentioned in previous chapters, RCC configuration is done in two steps, first by the first stage boot loader (FSBL TF-A) and then by the secure OS (OP-TEE).

Here are the corresponding device tree rcc sub node properties in fdts/stm32mp15xx-edx.dtsi consumed by the first stage boot loader (FSBL TF-A) to configure the clock tree required to boot on STM32MP135F-DK Discovery kit More info green.png:

&rcc {
	st,clksrc = <
		CLK_MPU_PLL1P
		CLK_AXI_PLL2P
		CLK_MLAHBS_PLL3
		CLK_CKPER_HSE
		CLK_RTC_LSE
		CLK_SDMMC1_PLL4P
		CLK_SDMMC2_PLL4P
		CLK_STGEN_HSE
		CLK_USBPHY_HSE
		CLK_I2C4_HSI
		CLK_USBO_USBPHY
		CLK_I2C12_HSI
		CLK_UART2_HSI
		CLK_UART4_HSI
		CLK_SAES_AXI
	>;

	st,clkdiv = <
		DIV(DIV_AXI, 0)
		DIV(DIV_MLAHB, 0)
		DIV(DIV_APB1, 1)
		DIV(DIV_APB2, 1)
		DIV(DIV_APB3, 1)
		DIV(DIV_APB4, 1)
		DIV(DIV_APB5, 2)
		DIV(DIV_APB6, 1)
		DIV(DIV_RTC, 0)
	>;

	st,pll_vco {
		pll1_vco_1300Mhz: pll1-vco-1300Mhz {
			src = < CLK_PLL12_HSE >;
			divmn = < 2 80 >;
			frac = < 0x800 >;
		};

		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
			src = < CLK_PLL12_HSE >;
			divmn = < 2 65 >;
			frac = < 0x1400 >;
		};

		pll3_vco_417_8Mhz: pll3-vco-417_8Mhz {
			src = < CLK_PLL3_HSE >;
			divmn = < 1 33 >;
			frac = < 0x1a04 >;
		};

		pll4_vco_600Mhz: pll4-vco-600Mhz {
			src = < CLK_PLL4_HSE >;
			divmn = < 1 49 >;
		};
	};

	/* VCO = 1300.0 MHz => P = 650 (CPU) */
	pll1:st,pll@0 {
		compatible = "st,stm32mp1-pll";
		reg = <0>;

		st,pll = < &pll1_cfg1 >;

		pll1_cfg1: pll1_cfg1 {
			st,pll_vco = < &pll1_vco_1300Mhz >;
			st,pll_div_pqr = < 0 1 1 >;
		};
	};

	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
	pll2:st,pll@1 {
		compatible = "st,stm32mp1-pll";
		reg = <1>;

		st,pll = < &pll2_cfg1 >;

		pll2_cfg1: pll2_cfg1 {
			st,pll_vco = < &pll2_vco_1066Mhz >;
			st,pll_div_pqr = < 1 1 0 >;
		};
	};

	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 209 */
	pll3:st,pll@2 {
		compatible = "st,stm32mp1-pll";
		reg = <2>;

		st,pll = < &pll3_cfg1 >;

		pll3_cfg1: pll3_cfg1 {
			st,pll_vco = < &pll3_vco_417_8Mhz >;
			st,pll_div_pqr = < 1 16 1 >;
		};
	};

	/* VCO = 600.0 MHz => P = 50, Q = 10, R = 100 */
	pll4:st,pll@3 {
		compatible = "st,stm32mp1-pll";
		reg = <3>;

		st,pll = < &pll4_cfg1 >;

		pll4_cfg1: pll4_cfg1 {
			st,pll_vco = < &pll4_vco_600Mhz >;
			st,pll_div_pqr = < 11 59 5 >;
		};
	};
};

Here are the corresponding device tree rcc sub node properties in core/arch/arm/dts/stm32mp135f-dk.dts consumed by the secure OS (OP-TEE) to configure the clock tree above:

&rcc {
	st,clksrc = <
		CLK_MPU_PLL1P
		CLK_AXI_PLL2P
		CLK_MLAHBS_PLL3
		CLK_RTC_LSE
		CLK_MCO1_HSE
		CLK_MCO2_DISABLED
		CLK_CKPER_HSE
		CLK_ETH1_PLL4P
		CLK_ETH2_PLL4P
		CLK_SDMMC1_PLL4P
		CLK_SDMMC2_PLL4P
		CLK_STGEN_HSE
		CLK_USBPHY_HSE
		CLK_I2C4_HSI
		CLK_USBO_USBPHY
		CLK_ADC2_CKPER
		CLK_I2C12_HSI
		CLK_UART1_HSI
		CLK_UART2_HSI
		CLK_UART35_HSI
		CLK_UART4_HSI
		CLK_UART6_HSI
		CLK_UART78_HSI
		CLK_SAES_AXI
		CLK_DCMIPP_PLL2Q
		CLK_LPTIM3_PCLK3
		CLK_RNG1_PLL4R
	>;

	st,clkdiv = <
		DIV(DIV_MPU, 1)
		DIV(DIV_AXI, 0)
		DIV(DIV_MLAHB, 0)
		DIV(DIV_APB1, 1)
		DIV(DIV_APB2, 1)
		DIV(DIV_APB3, 1)
		DIV(DIV_APB4, 1)
		DIV(DIV_APB5, 2)
		DIV(DIV_APB6, 1)
		DIV(DIV_RTC, 0)
		DIV(DIV_MCO1, 0)
		DIV(DIV_MCO2, 0)
	>;

	st,pll_vco {
		pll1_vco_2000Mhz: pll1-vco-2000Mhz {
			src = < CLK_PLL12_HSE >;
			divmn = < 1 82 >;
			frac = < 0xAAA >;
		};

		pll1_vco_1300Mhz: pll1-vco-1300Mhz {
			src = < CLK_PLL12_HSE >;
			divmn = < 2 80 >;
			frac = < 0x800 >;
		};

		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
			src = < CLK_PLL12_HSE >;
			divmn = < 2 65 >;
			frac = < 0x1400 >;
		};

		pll3_vco_417_8Mhz: pll3-vco-417_8Mhz {
			src = < CLK_PLL3_HSE >;
			divmn = < 1 33 >;
			frac = < 0x1a04 >;
		};

		pll4_vco_600Mhz: pll4-vco-600Mhz {
			src = < CLK_PLL4_HSE >;
			divmn = < 1 49 >;
		};
	};

	/* VCO = 1300.0 MHz => P = 650 (CPU) */
	pll1: st,pll@0 {
		compatible = "st,stm32mp1-pll";
		reg = <0>;

		st,pll = < &pll1_cfg1 >;

		pll1_cfg1: pll1_cfg1 {
			st,pll_vco = < &pll1_vco_1300Mhz >;
			st,pll_div_pqr = < 0 1 1 >;
		};

		pll1_cfg2: pll1_cfg2 {
			st,pll_vco = < &pll1_vco_2000Mhz >;
			st,pll_div_pqr = < 0 1 1 >;
		};
	};

	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
	pll2: st,pll@1 {
		compatible = "st,stm32mp1-pll";
		reg = <1>;

		st,pll = < &pll2_cfg1 >;

		pll2_cfg1: pll2_cfg1 {
			st,pll_vco = < &pll2_vco_1066Mhz >;
			st,pll_div_pqr = < 1 1 0 >;
		};
	};

	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
	pll3: st,pll@2 {
		compatible = "st,stm32mp1-pll";
		reg = <2>;

		st,pll = < &pll3_cfg1 >;

		pll3_cfg1: pll3_cfg1 {
			st,pll_vco = < &pll3_vco_417_8Mhz >;
			st,pll_div_pqr = < 1 16 36 >;
		};
	};

	/* VCO = 600.0 MHz => P = 50, Q = 10, R = 50 */
	pll4: st,pll@3 {
		compatible = "st,stm32mp1-pll";
		reg = <3>;
		st,pll = < &pll4_cfg1 >;

		pll4_cfg1: pll4_cfg1 {
			st,pll_vco = < &pll4_vco_600Mhz >;
			st,pll_div_pqr = < 11 59 11 >;
		};
	};

	st,clk_opp {
		/* CK_MPU clock config for MP13 */
		st,ck_mpu {

			cfg_1 {
				hz = < 1000000000 >;
				st,clksrc = < CLK_MPU_PLL1P >;
				st,pll = < &pll1_cfg2 >;
			};

			cfg_2 {
				hz = < 650000000 >;
				st,clksrc = < CLK_MPU_PLL1P >;
				st,pll = < &pll1_cfg1 >;
			};
		};
	};
};