Difference between revisions of "How to change the CPU frequency"

[quality revision] [quality revision]
m (CPU frequency configuration)
m
Applicable for STM32MP13x lines, STM32MP15x lines

1 Purpose[edit]

This article explains how to change the CPU operating point (also known as OPP). An operating point corresponds to the frequency of the processor and the voltage that needs to be supplied to sustain it.
It also shows how it is possible to define multiple operating points, allowing the system to jump among them at run time: this is the dynamic voltage and frequency scaling (DVFS). Some cautions are given at the end of the article, to help the user in its DVFS deployment.

2 Hardware side[edit]

On STM32MP1 Series products, the Cortex-A7 core:

  • can be clocked by PLL1 from the RCC internal peripheral: the PLL1P output frequency can be directly propagated to the core, or it can go through an intermediate MPUDIV divider
  • is supplied with
  • VDDCPU voltage on STM32MP13x lines Warning.png
  • VDDCORE voltage on STM32MP15x lines More info.png

The part number tells the device maximum supported frequency, up to 900 MHz 1 GHz for the STM32MP13 or up to 800 MHz for the STM32MP15, with associated usage conditions. Otherwise, the frequency must be kept below 650 MHz.

3 Software side[edit]

3.1 Boot time[edit]

By default, in OpenSTLinux distribution, TF-A BL2 sets the CPU frequency to 650 MHz, that is the maximum frequency sustainable with the nominal voltage.

Notice that the processor must receive the nominal voltage during TF-A BL2 execution, whether configuring the STPMIC1 from TF-A BL2 itself or getting it from a discrete power supply, depending on the hardware board configuration.

3.1.1 On STM32MP13x lines Warning.png[edit]

3.1.1.1 VDDCPU voltage configuration[edit]

The example below sets STPMIC1 BUCK1 minimal voltage to 1.25 V, allowing to provide the expected nominal voltage on VDDCPU for the CPU:

  vddcpu: buck1 {
    regulator-name = "vddcpu";
    regulator-min-microvolt = <1250000>;
    ...
};

3.1.1.2 CPU frequency configuration[edit]

TF-A recovers the CPU frequency configuration via the following Clock device tree configuration - Bootloader specific properties read:

&rcc {
	...
	st,clksrc = <
		CLK_MPU_PLL1P
		... >;

	st,pll_vco {
		...
		pll1_vco_1300Mhz: pll1-vco-1300Mhz {
			src = < CLK_PLL12_HSE >;
			divmn = < 2 80 >;
			frac = < 0x800 >;
		};
	};
	pll1:st,pll@0 {
		...
		st,pll = < &pll1_cfg1 >;
		...
		pll1_cfg1: pll1_cfg1 {
			st,pll_vco = < &pll1_vco_1300Mhz >;
			st,pll_div_pqr = < 0 1 1 >;
		};
	};

3.1.2 On STM32MP15x lines More info.png[edit]

3.1.2.1 VDDCORE voltage configuration[edit]

The example below sets STPMIC1 BUCK1 minimal voltage to 1.2 V, allowing to provide the expected nominal voltage on VDDCORE for the CPU:

  vddcore: buck1 {
    regulator-name = "vddcore";
    regulator-min-microvolt = <1200000>;
    ...
};

3.1.2.2 CPU frequency configuration[edit]

TF-A recovers the CPU frequency configuration via the following Clock device tree configuration - Bootloader specific properties read:

&rcc {
	...
	/* VCO = 1300.0 MHz => P = 650 (CPU) */
	pll1: st,pll@0 {
		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
		frac = < 0x800 >;
	};
	...
};

3.2 Runtime[edit]

3.2.1 On STM32MP13x lines Warning.png[edit]

3.2.1.1 Overview[edit]

By default, in OpenSTLinux distribution, the OP-TEE "soc extension" device tree file defines an OPP table that contains one or several frequency / voltage pair(s).

Info white.png Information
Whatever the implementation is, if your part number supports up to 900 MHz1 GHz, ensure that the VDDCPU minimum voltage is increased from 1.25 V to 1.35 V while running above 650 MHz
3.2.1.2 OPP table[edit]

At runtime, Linux will automatically request to OP-TEE SCMI interface to switch between the available operating points according to the CPU load and thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see Documentation/admin-guide/pm/cpufreq.rst ). This feature is called dynamic voltage and frequency scaling (DVFS).

For instance, in the example below, two operating points ([900 MHz 1 GHz ; 1.35 V]; [650 MHz ; 1.25 V]) are defined for a 900 MHz 1 GHz capable part number (opp-supported-hw = <0x2>):

&cpu0_opp_table {
		opp-9000000001000000000 {
			opp-hz = /bits/ 64 <9000000001000000000>;
			opp-microvolt = <1350000>;
			opp-supported-hw = <0x2>;
			st,opp-default;
		};

		opp-650000000 {
			opp-hz = /bits/ 64 <650000000>;
			opp-microvolt = <1250000>;
			opp-supported-hw = <0x2>;
		};
};

The PLL1 configurations needed to reach the above frequencies must be described via the 'st,clk_opp' property in 'rcc' device tree node, like this is visible in core/arch/arm/dts/stm32mp135f-dk.dts :

	st,clk_opp {
		st,ck_mpu {
			cfg_1 {
				hz = < 9000000001000000000 >;
				st,clksrc = < CLK_MPU_PLL1P >;
				st,pll = < &pll1_cfg2 >;
			};
			cfg_2 {
				hz = < 650000000 >;
				st,clksrc = < CLK_MPU_PLL1P >;
				st,pll = < &pll1_cfg1 >;
			};
		};
	};

Notes:

  • The operating point(s) supported by devices able to run above 650 MHz (and up to 900 MHz1 GHz) is/are identified by the opp-supported-hw property set to 0x2.
  • This description is valid for cold boot, but also when coming back from Standby low power mode.

3.2.2 On STM32MP15x lines More info.png[edit]

3.2.2.1 Overview[edit]

By default, in OpenSTLinux distribution, the Linux kernel "soc extension" device tree file defines an OPP table that contains one or several frequency / voltage pair(s).

Info white.png Information
Whatever the implementation is, if your part number supports up to 800 MHz, ensure that the VDDCORE minimum voltage is increased from 1.2 V to 1.35 V while running above 650 MHz
3.2.2.2 OPP table[edit]

At runtime, the Linux kernel will automatically switch between the available operating points according to the CPU load and thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see Documentation/admin-guide/pm/cpufreq.rst ). This feature is called dynamic voltage and frequency scaling (DVFS).

For instance, in the example below, two operating points ([800 MHz ; 1.35 V]; [400 MHz ; 1.2 V]) are defined for a 800 MHz capable part number (opp-supported-hw = <0x2>):

&cpu0_opp_table {
		opp-800000000 {
			opp-hz = /bits/ 64 <800000000>;
			opp-microvolt = <1350000>;
			opp-supported-hw = <0x2>;
		};
		opp-400000000 {
			opp-hz = /bits/ 64 <400000000>;
			opp-microvolt = <1200000>;
			opp-supported-hw = <0x2>;
			opp-suspend;
		};
};

Notes:

  • The operating point(s) supported by devices able to run above 650 MHz (and up to 800 MHz) is/are identified by the opp-supported-hw property set to 0x2.
  • This same OPP table must be present in both the BL32 (either OP-TEE or TF-A SP-MIN) and Linux device tree
  • This description is valid for cold boot, but also when coming back from Standby low power mode.
  • During cold boot, BL32 (either OP-TEE or TF-A SP-MIN) computes and saves the PLL1 settings for all operating points available in the device tree in compliance with the hardware capabilities. These saved paramaters are used later to increase the performance of the system-state transitions.

4 Dynamic voltage and frequency scaling (DVFS) caution[edit]

  • As stated above, as soon as at least two operating points are defined in the OPP table, Linux kernel will automatically switch between them at runtime thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see Documentation/admin-guide/pm/cpufreq.rst ). It is important to notice that cpufreq framework is only monitoring the CPU load to select the OPP because this can lead to some limitation during use cases where the CPU is not loaded a lot but high reactivity is needed to respect some real time constraints, like interrupt management. If you face some system issue where the CPU reactivity may be the root cause whereas DVFS is enabled, consider doing a trial with "performance" governor (see Documentation/admin-guide/pm/cpufreq.rst ).
  • Selecting OPP frequencies that can be reached with RCC MPUDIV dividor and without configuring again the PLL1 is recommended in order to get the fastest switch time between the OPP.


{{ApplicableFor
|MPUs list=STM32MP13x, STM32MP15x
|MPUs checklist=STM32MP13x, STM32MP15x
}}
==Purpose==
This article explains how to change the CPU '''operating point''' (also known as OPP). An operating point corresponds to the '''frequency''' of the processor and the  '''voltage''' that needs to be supplied to sustain it.<br>

It also shows how it is possible to define multiple operating points, allowing the system to jump among them at run time: this is the '''dynamic voltage and frequency scaling (DVFS)'''. Some cautions are given at the end of the article, to help the user in its DVFS deployment.

==Hardware side==
On {{MicroprocessorDevice | device=1}} products, the Cortex-A7 core:
* can be clocked by PLL1 from the [[RCC internal peripheral]]: the PLL1P output '''frequency''' can be directly propagated to the core, or it can go through an intermediate MPUDIV divider
* is supplied with 
:* VDDCPU '''voltage''' on {{MicroprocessorDevice | device=13}}
:* VDDCORE '''voltage''' on {{MicroprocessorDevice | device=15}}
The '''part number''' tells the device maximum supported frequency, up to 900 MHz1 GHz for the [[STM32MP13_microprocessor#Part_number_codification|STM32MP13]] or up to 800 MHz for the [[STM32MP15_microprocessor#Part_number_codification|STM32MP15]], with associated usage conditions. Otherwise, the frequency must be kept below 650 MHz.

==Software side==
=== Boot time ===
By default, in OpenSTLinux distribution, TF-A BL2 sets the CPU frequency to 650 MHz, that is the maximum frequency sustainable with the nominal voltage.<br><br>


Notice that the processor must receive the nominal voltage during TF-A BL2 execution, whether configuring the STPMIC1 from TF-A BL2 itself or getting it from a discrete power supply, depending on the hardware board configuration.

==== On {{MicroprocessorDevice | device=13}} ====
===== VDDCPU voltage configuration =====
The example below sets STPMIC1 BUCK1 minimal voltage to 1.25 V, allowing to provide the expected nominal voltage on VDDCPU for the CPU:<syntaxhighlight lang="c">

  vddcpu: buck1 {
    regulator-name = "vddcpu";
    regulator-min-microvolt = <1250000>;
    ...
};</syntaxhighlight>


===== CPU frequency configuration =====
TF-A recovers the CPU frequency configuration via the following [[Clock device tree configuration - Bootloader specific]] properties read:
<syntaxhighlight lang="c">

&rcc {
	...
	st,clksrc = <
		CLK_MPU_PLL1P
		...>;

	st,pll_vco {
		...
		pll1_vco_1300Mhz: pll1-vco-1300Mhz {
			src = < CLK_PLL12_HSE >;
			divmn = < 2 80 >;
			frac = < 0x800 >;
		};
	};
	pll1:st,pll@0 {
		...
		st,pll = < &pll1_cfg1 >;
		...
		pll1_cfg1: pll1_cfg1 {
			st,pll_vco = < &pll1_vco_1300Mhz >;
			st,pll_div_pqr = < 0 1 1 >;
		};
	};</syntaxhighlight>


==== On {{MicroprocessorDevice | device=15}} ====
===== VDDCORE voltage configuration =====
The example below sets STPMIC1 BUCK1 minimal voltage to 1.2 V, allowing to provide the expected nominal voltage on VDDCORE for the CPU:<syntaxhighlight lang="c">

  vddcore: buck1 {
    regulator-name = "vddcore";
    regulator-min-microvolt = <1200000>;
    ...
};</syntaxhighlight>

===== CPU frequency configuration =====
TF-A recovers the CPU frequency configuration via the following [[Clock device tree configuration - Bootloader specific]] properties read:<syntaxhighlight lang="c">

&rcc {
	...
	/* VCO = 1300.0 MHz => P = 650 (CPU) */
	pll1: st,pll@0 {
		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
		frac = < 0x800 >;
	};
	...
};</syntaxhighlight>


=== Runtime ===
==== On {{MicroprocessorDevice | device=13}} ====
===== Overview =====
By default, in OpenSTLinux distribution, the OP-TEE [[STM32 MPU device tree|"soc extension" device tree]] file defines an '''OPP table''' that contains one or several frequency / voltage pair(s).

{{Info | Whatever the implementation is, if your [[STM32MP13_microprocessor#Part_number_codification|part number]] supports up to 900 MHz1 GHz, ensure that the VDDCPU minimum '''voltage''' is increased from 1.25 V to 1.35 V while running above 650 MHz}}

===== OPP table =====
At runtime, Linux will automatically request to [[SCMI overview|OP-TEE SCMI]] interface to switch between the available operating points according to the CPU load and thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see {{CodeSource | Linux kernel | Documentation/admin-guide/pm/cpufreq.rst}}). This feature is called dynamic voltage and frequency scaling (DVFS).<br>


For instance, in the example below, two operating points ([900 MHz1 GHz ; 1.35 V]; [650 MHz ; 1.25 V]) are defined for a 900 MHz1 GHz capable part number (opp-supported-hw = <0x2>):<syntaxhighlight lang="c">

&cpu0_opp_table {
		opp-9000000001000000000 {
			opp-hz = /bits/ 64 <900000000><1000000000>;
			opp-microvolt = <1350000>;
			opp-supported-hw = <0x2>;
			st,opp-default;
		};

		opp-650000000 {
			opp-hz = /bits/ 64 <650000000>;
			opp-microvolt = <1250000>;
			opp-supported-hw = <0x2>;
		};
};</syntaxhighlight>

The PLL1 configurations needed to reach the above frequencies must be described via the 'st,clk_opp' property in 'rcc' device tree node, like this is visible in {{CodeSource | OP-TEE_OS | core/arch/arm/dts/stm32mp135f-dk.dts}}:<syntaxhighlight lang="c">

	st,clk_opp {
		st,ck_mpu {
			cfg_1 {
				hz = < 900000000 >< 1000000000 >;
				st,clksrc = < CLK_MPU_PLL1P >;
				st,pll = < &pll1_cfg2 >;
			};
			cfg_2 {
				hz = < 650000000 >;
				st,clksrc = < CLK_MPU_PLL1P >;
				st,pll = < &pll1_cfg1 >;
			};
		};
	};</syntaxhighlight>

Notes:
* The operating point(s) supported by devices able to run above 650 MHz (and up to 900 MHz1 GHz) is/are identified by the '''opp-supported-hw''' property set to 0x2.
* This description is valid for cold boot, but also when coming back from [[Power overview|Standby]] low power mode.

==== On {{MicroprocessorDevice | device=15}} ====
===== Overview =====
By default, in OpenSTLinux distribution, the Linux kernel [[STM32 MPU device tree|"soc extension" device tree]] file defines an '''OPP table''' that contains one or several frequency / voltage pair(s).
{{Info | Whatever the implementation is, if your [[STM32MP15_microprocessor#Part_number_codification|part number]] supports up to 800 MHz, ensure that the VDDCORE minimum '''voltage''' is increased from 1.2 V to 1.35 V while running above 650 MHz}}

===== OPP table =====
At runtime, the Linux kernel will automatically switch between the available operating points according to the CPU load and thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see {{CodeSource | Linux kernel | Documentation/admin-guide/pm/cpufreq.rst}}). This feature is called dynamic voltage and frequency scaling (DVFS).<br>


For instance, in the example below, two operating points ([800 MHz ; 1.35 V]; [400 MHz ; 1.2 V]) are defined for a 800 MHz capable part number (opp-supported-hw = <0x2>):<syntaxhighlight lang="c">

&cpu0_opp_table {
		opp-800000000 {
			opp-hz = /bits/ 64 <800000000>;
			opp-microvolt = <1350000>;
			opp-supported-hw = <0x2>;
		};
		opp-400000000 {
			opp-hz = /bits/ 64 <400000000>;
			opp-microvolt = <1200000>;
			opp-supported-hw = <0x2>;
			opp-suspend;
		};
};</syntaxhighlight>

Notes:
* The operating point(s) supported by devices able to run above 650 MHz (and up to 800 MHz) is/are identified by the '''opp-supported-hw''' property set to 0x2.
* This same OPP table must be present in both the BL32 (either OP-TEE or TF-A SP-MIN) and Linux device tree
* This description is valid for cold boot, but also when coming back from [[Power overview|Standby]] low power mode.
* During cold boot, BL32 (either OP-TEE or TF-A SP-MIN) computes and saves the PLL1 settings for all operating points available in the device tree in compliance with the hardware capabilities. These saved paramaters are used later to increase the performance of the system-state transitions.

==Dynamic voltage and frequency scaling (DVFS) caution==
* As stated above, as soon as at least two operating points are defined in the OPP table, Linux kernel will automatically switch between them at runtime thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see {{CodeSource | Linux kernel | Documentation/admin-guide/pm/cpufreq.rst}}). It is important to notice that cpufreq framework is only monitoring the CPU load to select the OPP because this can lead to some limitation during use cases where the CPU is not loaded a lot but high reactivity is needed to respect some real time constraints, like interrupt management. If you face some system issue where the CPU reactivity may be the root cause whereas DVFS is enabled, consider doing a trial with "performance" governor (see {{CodeSource | Linux kernel | Documentation/admin-guide/pm/cpufreq.rst}}).
* Selecting OPP frequencies that can be reached with [[RCC internal peripheral|RCC]] MPUDIV dividor and without configuring again the PLL1 is recommended in order to get the fastest switch time between the OPP. <noinclude>

[[Category:How to customize software]]
{{PublicationRequestId | 14900 | 2020-02-11 | AnneJ}}</noinclude>
Line 13: Line 13:
 
:* VDDCPU '''voltage''' on {{MicroprocessorDevice | device=13}}
 
:* VDDCPU '''voltage''' on {{MicroprocessorDevice | device=13}}
 
:* VDDCORE '''voltage''' on {{MicroprocessorDevice | device=15}}
 
:* VDDCORE '''voltage''' on {{MicroprocessorDevice | device=15}}
The '''part number''' tells the device maximum supported frequency, up to 900 MHz for the [[STM32MP13_microprocessor#Part_number_codification|STM32MP13]] or up to 800 MHz for the [[STM32MP15_microprocessor#Part_number_codification|STM32MP15]], with associated usage conditions. Otherwise, the frequency must be kept below 650 MHz.
+
The '''part number''' tells the device maximum supported frequency, up to 1 GHz for the [[STM32MP13_microprocessor#Part_number_codification|STM32MP13]] or up to 800 MHz for the [[STM32MP15_microprocessor#Part_number_codification|STM32MP15]], with associated usage conditions. Otherwise, the frequency must be kept below 650 MHz.
   
 
==Software side==
 
==Software side==
Line 90: Line 90:
 
By default, in OpenSTLinux distribution, the OP-TEE [[STM32 MPU device tree|"soc extension" device tree]] file defines an '''OPP table''' that contains one or several frequency / voltage pair(s).
 
By default, in OpenSTLinux distribution, the OP-TEE [[STM32 MPU device tree|"soc extension" device tree]] file defines an '''OPP table''' that contains one or several frequency / voltage pair(s).
   
{{Info | Whatever the implementation is, if your [[STM32MP13_microprocessor#Part_number_codification|part number]] supports up to 900 MHz, ensure that the VDDCPU minimum '''voltage''' is increased from 1.25 V to 1.35 V while running above 650 MHz}}
+
{{Info | Whatever the implementation is, if your [[STM32MP13_microprocessor#Part_number_codification|part number]] supports up to 1 GHz, ensure that the VDDCPU minimum '''voltage''' is increased from 1.25 V to 1.35 V while running above 650 MHz}}
   
 
===== OPP table =====
 
===== OPP table =====
 
At runtime, Linux will automatically request to [[SCMI overview|OP-TEE SCMI]] interface to switch between the available operating points according to the CPU load and thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see {{CodeSource | Linux kernel | Documentation/admin-guide/pm/cpufreq.rst}}). This feature is called dynamic voltage and frequency scaling (DVFS).<br>
 
At runtime, Linux will automatically request to [[SCMI overview|OP-TEE SCMI]] interface to switch between the available operating points according to the CPU load and thanks to Linux cpufreq framework, configured with "ondemand" governor policy (see {{CodeSource | Linux kernel | Documentation/admin-guide/pm/cpufreq.rst}}). This feature is called dynamic voltage and frequency scaling (DVFS).<br>
   
For instance, in the example below, two operating points ([900 MHz ; 1.35 V]; [650 MHz ; 1.25 V]) are defined for a 900 MHz capable part number (opp-supported-hw = <0x2>):
+
For instance, in the example below, two operating points ([1 GHz ; 1.35 V]; [650 MHz ; 1.25 V]) are defined for a 1 GHz capable part number (opp-supported-hw = <0x2>):
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 
&cpu0_opp_table {
 
&cpu0_opp_table {
opp-900000000 {
+
opp-1000000000 {
opp-hz = /bits/ 64 <900000000>;
+
opp-hz = /bits/ 64 <1000000000>;
 
opp-microvolt = <1350000>;
 
opp-microvolt = <1350000>;
 
opp-supported-hw = <0x2>;
 
opp-supported-hw = <0x2>;
Line 117: Line 117:
 
st,ck_mpu {
 
st,ck_mpu {
 
cfg_1 {
 
cfg_1 {
hz = < 900000000 >;
+
hz = < 1000000000 >;
 
st,clksrc = < CLK_MPU_PLL1P >;
 
st,clksrc = < CLK_MPU_PLL1P >;
 
st,pll = < &pll1_cfg2 >;
 
st,pll = < &pll1_cfg2 >;
Line 130: Line 130:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
Notes:
 
Notes:
* The operating point(s) supported by devices able to run above 650 MHz (and up to 900 MHz) is/are identified by the '''opp-supported-hw''' property set to 0x2.
+
* The operating point(s) supported by devices able to run above 650 MHz (and up to 1 GHz) is/are identified by the '''opp-supported-hw''' property set to 0x2.
 
* This description is valid for cold boot, but also when coming back from [[Power overview|Standby]] low power mode.
 
* This description is valid for cold boot, but also when coming back from [[Power overview|Standby]] low power mode.