CPU frequency scaling
Introduction
This page gives an overview of the CPU freq driver which is available as part of the ZynqMP Linux distribution.
Paths, files, links and documentation on this page are given relative to the Linux kernel source tree.
It is documented in Documentation/cpu-freq/.
Cpufreq often uses the Operating Performance Point library, which is explained in Documentation/power/opp.txt. The cpufreq framework comes with different frequency scaling governors, which scale the CPU frequency according to system load (for details please refer to the documentation).
The driver exposes a control interface through sysFS in /sys/devices/system/cpu/cpu0/cpufreq/.
In the above example the acpu frequencies are limited to pllfreq/x where x is integral numbers 1, 2 , 3 .. etc
pllfreq = osc_frequency * PLL_multiplier
Lets take the example of zcu102
In zcu102 the osc frequency is 33.33
The default hdf has PLL multiplier of 72.
pllfreq = 33.33*72 = 2399.76
the possible frequencies are integral divisors of 2399.76M
1199.88 M
799.92 M
599.94 M
479.95M
399.96M
342.82M
etc
None
zynq:
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
Devicetree
Paths, files, links and documentation on this page are given relative to the Linux kernel source tree.
It is documented in Documentation/cpu-freq/.
Cpufreq often uses the Operating Performance Point library, which is explained in Documentation/power/opp.txt. The cpufreq framework comes with different frequency scaling governors, which scale the CPU frequency according to system load (for details please refer to the documentation).
The driver exposes a control interface through sysFS in /sys/devices/system/cpu/cpu0/cpufreq/.
HW IP features
Dynamic frequency scaling for Zynqmp Ultrascale+ MPSoc APU.Features supported in driver
Dynamic frequency scaling for Zynqmp Ultrascale+ MPSoc APU.Frequencies supported in Zynq Ultrascale+ MPSoC
We do not support changing the parent pll rates (pllfreq). We support only integral divisors of pllfreq.In the above example the acpu frequencies are limited to pllfreq/x where x is integral numbers 1, 2 , 3 .. etc
pllfreq = osc_frequency * PLL_multiplier
Lets take the example of zcu102
In zcu102 the osc frequency is 33.33
The default hdf has PLL multiplier of 72.
pllfreq = 33.33*72 = 2399.76
the possible frequencies are integral divisors of 2399.76M
1199.88 M
799.92 M
599.94 M
479.95M
399.96M
342.82M
etc
Missing Features, Known Issues and Limitations
zynqmp Ultrascale+:None
zynq:
- When running at a too low frequency, USB breaks. The lowest tested and working frequency is 222.222 MHz. Highest frequency where it is known broken is 111.111 MHz
- Suspend breaks on reduced frequencies
- Due to dependencies between the CPU frequency and timers, the range of valid frequencies is limited/frequency changes may fail (see: https://github.com/Xilinx/linux-xlnx/commit/356cbded4131b067ec5fa4430c15c2fac867fa2b)
- cpufreq statistics don't work
- System clock runs slower proportionately to the difference between the default clock rate and that set by cpufreq if a timer other than the TTC (e.g. arm_global_timer) is used as clocksource
Kernel Configuration
The following config options should be enabled in order to build the cpufreq driverCONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
Symbol: CPU_FREQ [=y] Type : boolean Prompt: CPU Frequency scaling Location: -> CPU Power Management -> CPU Frequency scaling Defined at drivers/cpufreq/Kconfig:3 Selects: SRCU [=y]
cpus { #address-cells = <1>; #size-cells = <0>; cpu0: cpu@0 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; operating-points-v2 = <&&cpu_opp_table>; reg = <0x0>; cpu-idle-states = <&&CPU_SLEEP_0>; }; cpu1: cpu@1 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x1>; operating-points-v2 = <&&cpu_opp_table>; cpu-idle-states = <&&CPU_SLEEP_0>; }; cpu2: cpu@2 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x2>; operating-points-v2 = <&&cpu_opp_table>; cpu-idle-states = <&&CPU_SLEEP_0>; }; cpu3: cpu@3 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x3>; operating-points-v2 = <&&cpu_opp_table>; cpu-idle-states = <&&CPU_SLEEP_0>; }; cpu_opp_table: cpu_opp_table { compatible = "operating-points-v2"; opp-shared; opp00 { opp-hz = /bits/ 64 <1199999988>; opp-microvolt = <1000000>; clock-latency-ns = <500000>; }; opp01 { opp-hz = /bits/ 64 <599999994>; opp-microvolt = <1000000>; clock-latency-ns = <500000>; }; opp02 { opp-hz = /bits/ 64 <399999996>; opp-microvolt = <1000000>; clock-latency-ns = <500000>; }; opp03 { opp-hz = /bits/ 64 <299999997>; opp-microvolt = <1000000>; clock-latency-ns = <500000>; }; };
Test Procedure
/sys/devices/system/cpu/cpufreq/policy0/stats/ti 275000 0 366666 0 550000 0 1100000 18170 roott@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# cat affected_cpu 0 1 2 3 root@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# ilable_frequenciesREMUS:/sys/devices/system/cpu/cpufreq/policy0# cat scaling_ava 275000 366666 550000 1100000 root@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# root@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# ilable_governors REMUS:/sys/devices/system/cpu/cpufreq/policy0# cat scaling_avai conservative ondemand userspace powersave performance root@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# root@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# scaling_setspeed -REMUS:/sys/devices/system/cpu/cpufreq/policy0# echo 275000 > PMUFW: PmMmioRead: (NODE_APU) addr=0xFD1A0060, value=0x3000200 PMUFW: PmMmioWrite: (NODE_APU) addr=0xFD1A0060, mask=0xFFFFFFFF, value=0x3000500 PMUFW: PmMmioRead: (NODE_APU) addr=0xFD1A0060, value=0x3000500 root@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# _freq ilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# cat scaling_cur 275000 in_state nx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0# cat stats/time_i 275000 3275 366666 0 550000 0 1100000 32448 root@Xilinx-EP108-REMUS:/sys/devices/system/cpu/cpufreq/policy0#
Mainline status
The driver is currently in sync with the mainline.Change Log
2024.2
None
2024.1
None
2023.2
None
2023.1
None
2022.2
None
2022.1
None
2021.2
None
2021.1
None
None
2021.1
None
None
2020.2
None
None
2019.1
None
None
2019.2
None
None
2018.3
None
None
2018.2
None
None
2018.1
None
None
2017.4
None
None
2017.3
None
None
2017.2
None
2017.1
Summary:
ca1cf28 cpufreq: dt: Add zynqmp to the cpufreq dt platdev
c0b91f5 dts: zynqmp: Update the OPPs for cpu freq
Summary:
- Added device tree node
- Added cpufreq driver support
ca1cf28 cpufreq: dt: Add zynqmp to the cpufreq dt platdev
c0b91f5 dts: zynqmp: Update the OPPs for cpu freq
Related Links
||
||
cpus { | |
#address-cells = <1>; | |
#size-cells = <0>; | |
cpu0: cpu@0 { | |
compatible = "arm,cortex-a53", "arm,armv8"; | |
device_type = "cpu"; | |
enable-method = "psci"; | |
operating-points-v2 = <&cpu_opp_table>; | |
reg = <0x0>; | |
cpu-idle-states = <&CPU_SLEEP_0>; | |
}; | |
cpu1: cpu@1 { | |
compatible = "arm,cortex-a53", "arm,armv8"; | |
device_type = "cpu"; | |
enable-method = "psci"; | |
reg = <0x1>; | |
operating-points-v2 = <&cpu_opp_table>; | |
cpu-idle-states = <&CPU_SLEEP_0>; | |
}; | |
cpu2: cpu@2 { | |
compatible = "arm,cortex-a53", "arm,armv8"; | |
device_type = "cpu"; | |
enable-method = "psci"; | |
reg = <0x2>; | |
operating-points-v2 = <&cpu_opp_table>; | |
cpu-idle-states = <&CPU_SLEEP_0>; | |
}; | |
cpu3: cpu@3 { | |
compatible = "arm,cortex-a53", "arm,armv8"; | |
device_type = "cpu"; | |
enable-method = "psci"; | |
reg = <0x3>; | |
operating-points-v2 = <&cpu_opp_table>; | |
cpu-idle-states = <&CPU_SLEEP_0>; | |
}; | |
idle-states { | |
entry-method = "arm,psci"; | |
CPU_SLEEP_0: cpu-sleep-0 { | |
compatible = "arm,idle-state"; | |
arm,psci-suspend-param = <0x40000000>; | |
local-timer-stop; | |
entry-latency-us = <300>; | |
exit-latency-us = <600>; | |
min-residency-us = <100000>; | |
}; | |
}; | |
}; | |
cpu_opp_table: cpu_opp_table { | |
compatible = "operating-points-v2"; | |
opp-shared; | |
opp00 { | |
opp-hz = /bits/ 64 <1199999988>; | |
opp-microvolt = <1000000>; | |
clock-latency-ns = <500000>; | |
}; | |
opp01 { | |
opp-hz = /bits/ 64 <599999994>; | |
opp-microvolt = <1000000>; | |
clock-latency-ns = <500000>; | |
}; | |
opp02 { | |
opp-hz = /bits/ 64 <399999996>; | |
opp-microvolt = <1000000>; | |
clock-latency-ns = <500000>; | |
}; | |
opp03 { | |
opp-hz = /bits/ 64 <299999997>; | |
opp-microvolt = <1000000>; | |
clock-latency-ns = <500000>; | |
}; | |
}; | |
© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy