I have been wondering why no proper CPU frequency scaling driver has been implemented for WRT3200ACM (and WRT1900ACS etc.) and the other mvebu devices.
Apparently no such driver has been accepted upstream in Linux, but luckily there is one RFC version of a driver, which has been published in 2015. I noticed that the driver has recently been implemented for Turris Omnia (running an Openwrt derivative with kernel 4.4 for mvebu), so I decided to test if the driver could be modified to work with kernel 4.9.
I succeeded in modifying the driver. So far it has worked ok in my WRT3200ACM. Based on my experience, it scales ok, and running the CPU at half of the max frequency when idle (most of the time) lowers CPU temperature by some 2 degrees.
Before I create a pull request, it would be interesting to get feedback from others, if it works and is stable also in the other routers of the WRT1900ACx family.
Ps. does anybody know it the processor can be run with other clock speeds? The upstream authors have implemented only 100% and 50% operating points, but other devices scale with more granular steps (like R7800 IPQ8065 with 6 steps from 384 to 1700). So I wonder if the Marvell mvebu has stricter limitations in clock speeds, or if there could be found other operating points (like 1/4 etc.)...
commit for kernel 4.14
OLD VERSION still with 805.patch:
commit for kernel 4.14
Note: I haven’t yet updated the commit in this thread, so it creates six patches 801-806, but after the most recent kernel 4.14. version bump, the patch 805 needs to be deleted, as it is unnecessary and breaks compilation.
EVEN OLDER VERSION:
The following commit creates the six kernel patches that implement the driver for kernel 4.9
downloadable patch for kernel 4.9: https://github.com/hnyman/source/commit/0ab4712d63ef1dd34fade8fe870c9de0ce41c1ac.patch
Add CPU frequency scaling driver for mvebu Armada XP/380/385.
The driver supports only the 100% and 50% operating points for the CPU. Linux scales the CPU frequency automatically according to the CPU load.
Both CPU cores are scaled simultaneously in 380/385.
Armada XP cores may have independent clocks, but I can't verify that.
The driver has been originally published by Gregory Clement in Linux kernel mailing list in July 2015 as RFC, but no final version of the driver has been published. Reference to messages starting at:
Note: upstream messages mention possible instability under heavy I/O.
The driver has been adapted for Turris Omnia running kernel 4.4. It is used in the current Turris versions since this commit:
I have adapted the driver for kernel 4.9. The necessary changes were mainly minor context changes, with the exception of:
- the driver initialiation routine has been moved from pmsu.c to cpufreq.c so use include/linux/mvebu-pmsu.h to pass variables and functions between pmsu.c and cpufreq.c
- data structure for cpufreq-dt has been simplified upstream, so drop the unused independent clocks argument and simplify driver registration according to upstream changes.
Run-tested with WRT3200ACM (Armada 385) at LEDE master r3910-20e40db524
Upstream WIP code can be found at
Based on that it is possible that Armada XP (original WRT1900AC, mamba) requires two additional commits to be stable.
root@LEDE:~# cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq 1866000 1866000 root@LEDE:~# kill 6166 root@LEDE:~# cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq 933000 933000 root@LEDE:~# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ondemand performance root@LEDE:~# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ondemand