Loading...
 

Enable Power Management on MACCHIATObin

Introduction

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

Bootloader

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
NOTICE:  Done

 

Kernel

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.

 Note

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
20231
# cat /sys/devices/system/cpu/cpu3/cpuidle/state1/usage
36007


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

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

 

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


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
11

 
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
100000

 
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.