Enable Power Management on MACCHIATObin


This page will walk you through the instructions on how to build the binaries for MACCHIATObin to enable the CPU level of power management features including:

  • CPU Idle Management
  • CPU Host Plug Management
  • CPU Frequency Scaling

And we'll also go through the commands of how to execute and check these features on MACCHIATObin.

Build binaries


The bootloader image has to be rebuilt for MACCHIATObin in order to enable the power management feature. It is necessary to have the power management firmware included in the bootloader image. The power management firmware is running on the Armada8040 SoC Management Subsystem(MSS).

Please download the MSS firmware in the link here, and copy the file to your Linux build machine. Then setup this file as the SCP_BL2 payload to the ATF.

mcbin@buildserver:~/cm3$ export SCP_BL2=/home/mcbin/cm3/RTOSDemo-cm3.bin

Next, follow the instructions in Build from source - Bootloader to rebuild the bootloader image for MACCHIATObin. The purpose of rebuilding the bootloader image is to include MSS firmware(SCP_BL2) into the image. Therefore, the u-boot steps in the instruction page may be skipped if you have already built the u-boot binary. Once you have the new bootloader image ready, please follow the instruction page Update the Bootloader to update the bootloader image on the MACCHIATObin.

When you have the new bootloader updated on your MACCHIATObin, you may check the log output to confirm you have the correct image written. Upon the reboot of the board, please find the below information printed on your console before the U-boot runs.

BL2: Initiating SCP_BL2 transfer to SCP
NOTICE:  Load image to AP MSS
NOTICE:  Loading MSS image from address 0x4023000 Size 0x559c to MSS at 0xf0580000



The current Linux defconfig for MACCHIATObin has already enabled the CPU Idle and CPU Hot plug feature. CPU Idle feature also requires additional configurations to the power state in the Linux device tree. Below is an example of the code changes to activate the CPU Idle for MACCHIATObin, you'll need to update the dtsi file in the kernel source tree:

diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
index 8d1c433..148b7c8 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
@@ -61,7 +61,7 @@
                        clocks = <&ap806_clock 0>;
                        operating-points-v2 = <&cluster0_opp>;
                        enable-method = "psci";
-                       cpu-idle-states;
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                cpu1: cpu@001 {
                        device_type = "cpu";
@@ -70,7 +70,7 @@
                        clocks = <&ap806_clock 0>;
                        operating-points-v2 = <&cluster0_opp>;
                        enable-method = "psci";
-                       cpu-idle-states;
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                cpu2: cpu@100 {
                        device_type = "cpu";
@@ -79,7 +79,7 @@
                        clocks = <&ap806_clock 1>;
                        operating-points-v2 = <&cluster1_opp>;
                        enable-method = "psci";
-                       cpu-idle-states;
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                cpu3: cpu@101 {
                        device_type = "cpu";
@@ -88,7 +88,7 @@
                        clocks = <&ap806_clock 1>;
                        operating-points-v2 = <&cluster1_opp>;
                        enable-method = "psci";
-                       cpu-idle-states;
+                       cpu-idle-states = <&CPU_SLEEP_0>;

The change is based on the repository https://github.com/MarvellEmbeddedProcessors/linux-marvell/tree/linux-4.4.52-armada-17.04 . Please also find the complete file arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi here.

Please follow the instructions in Build from source - Kernel to rebuild the kernel with the changes above and you'll get the kernel binary/dtb to support the CPU Idle feature.

Operating Power Management

Linux is the initiator of all power management functionality (CPU Hot Plug, CPU Idle, Frequency Scaling etc). Some features are initiated by Linux without user interference and some are triggered by the user.


The example commands below are run in the Buildroot root file system. You should be able to use the same commands with other root file system on MACCHIATObin.

CPU Idle

The CPU Idle feature is initiated by Linux (without user interference) whenever it thinks that the core is not loaded enough and can be turned off. In the case of all cores of one cluster are turned off, the cluster will be turned off as well. The cores (and cluster) are awakened when Linux decides that there is enough load or in case of an event (interrupt from an IO for example).

To check the number of times one CPU enters to a specific state, please do:

cat /sys/devices/system/cpu/cpu[x x=0-3]/cpuidle/state[y y=0-1]/usage

Here the state0 means wait for interrupt, state1 means deep idle. For example, if you want to check the cpu3 usage, please use the command below:

# cat /sys/devices/system/cpu/cpu3/cpuidle/state0/usage
# cat /sys/devices/system/cpu/cpu3/cpuidle/state1/usage

To display the total duration one CPU spends in a certain power state:

# cat /sys/devices/system/cpu/cpu3/cpuidle/state0/time
# cat /sys/devices/system/cpu/cpu3/cpuidle/state1/time


CPU Hot Plug

CPU Hot Plug feature enables the user the option to dynamically remove and add cores.

In order to turn off a core (for example, core 2), type in Linux prompt:

# echo 0 > /sys/devices/system/cpu/cpu2/online
[13986.423265] IRQ151 no longer affine to CPU2
[13986.427495] CPU2: shutdown
[13986.430212] psci: CPU2 killed.

To turn it on again:

# echo 1 > /sys/devices/system/cpu/cpu2/online
[14057.235292] Detected PIPT I-cache on CPU2
[14057.239348] CPU2: Booted secondary processor [410fd081]

In order to see which cores are on, you can use:

# cat /proc/cpuinfo

Or, use:

# cat /proc/interrupts

The example below shows the cpuinfo after cpu1,2,3 are turned off.

# cat /proc/cpuinfo
processor       : 0
BogoMIPS        : 50.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd08
CPU revision    : 1


CPU Frequency Scaling

CPU frequency scaling enables the operating system to scale the CPU frequency up or down in order to save power. CPU frequency can be scaled automatically depending on the system load, or manually by userspace programs.

CPU frequency scaling supports several scaling governors that dictate when and how CPU is scaled up/down. To check the available governors on a specific CPU(e.g. cpu3), please use the example command below:

# cat /sys/devices/system/cpu/cpu3/cpufreq/scaling_available_governors
ondemand userspace performance

To check the current cpufreq governor:

# cat /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

performance is the default scaling governor chosen for MACCHIATObin, it means to run the CPU at the maximum frequency. We can use the command to change it to ondemand, meaning the CPU scales its frequency dynamically according to current load:

# echo ondemand > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

After we select the scaling governor to ondemand, we can check the scaling statistics with the command:

#  cat /sys/devices/system/cpu/cpu3/cpufreq/stats/time_in_state
100000 27240
433333 306
650000 194
1300000 52450

The output show how long time the CPU states in each of the different frequency. We can also check how many frequency transitions are made:

#  cat /sys/devices/system/cpu/cpu3/cpufreq/stats/total_trans

If you want to change the CPU frequency manually, first you'll need to set the correct governor:

# echo userspace > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

Next, check the available frequencies you can set to that CPU:

# cat /sys/devices/system/cpu/cpu3/cpufreq/scaling_available_frequencies
100000 433333 650000 1300000

Now you can modify the CPU frequency to the desired value:

# echo 100000 > /sys/devices/system/cpu/cpu3/cpufreq/scaling_setspeed

To confirm if the modification is successful, check the current CPU frequency after the modification:

# cat /sys/devices/system/cpu/cpu3/cpufreq/scaling_cur_freq

You may also check the CPU frequency statistics by reading the files such as /sys/devices/system/cpu/cpu3/cpufreq/stats/total_trans and /sys/devices/system/cpu/cpu3/cpufreq/stats/time_in_state, similar to what we have done previously when the scaling governor is ondemand.