CPU frequency scaling driver for mvebu (WRT3200ACM etc.)


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

as a patch:

OLD VERSION still with 805.patch:

commit for kernel 4.14

as a patch:

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.

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

root@LEDE:~# kill 6166

root@LEDE:~# cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq

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

Need New DavidC502 Thread
Need New DavidC502 Thread
Need New DavidC502 Thread
[Solved] WRT1900ACV1 reboots: kernel 4.9
Netgear R7800 exploration (IPQ8065, QCA9984)
Build for Netgear R7800
Updating u-boot on wrt1200ac / Overclocking cpu

If somebody wants to test the WRT3200ACM build that has CPU frequency scaling enabled, it can be found here, including all source code modifications. The build includes the same packages as my R7800 and WNDR3700 community builds.


I am not going to start one more community build for the device series, but may post test builds every now and then.

Ps. I tested and built a 17.01 version with kernel 4.4 first, but I don't think that it is relevant any more, as new stuff gets introduced to master

Build for Netgear R7800

Hi @hnyman. Now tested Your patch and it work OK.


So this will be pushed upstream ?


I'd love to test this for my WRT1900AC-V2

could you tell me how to apply this to a build for my router?


You can apply the patch pretty easily!Y, the standard way...

Go to your buildroot root
Download the patch with ever from github. Direct link above.
Apply the patch with "patch -p 1 -i filename
Recompile firmware (after make clean)


Do you mean Linux? Not likely as the original author has already sent it to Linux mailing list in 2015 and it has not been accepted then.

I could do a PR for LEDE but so far there has not been much feedback. And in my own tests the temperature decrease is rather modest, so I am not sure how useful this is in reality.


sigh, stupid me actually missed your first post, so i only saw the github from gclement initially.
compiling now with the new patches :slight_smile:


OK, it's running on my WRT1900AC-V2.
I see it switch from 800MHZ to 1.6GHZ, when i apply some load.
wondering if we can tune it back even further?

Still seeing these messages in dmesg though:

[    0.030095] mvebu-pmsu: CPU hotplug support is currently broken on Armada 38x: disabling
[    0.030102] mvebu-pmsu: CPU idle is currently broken on Armada 38x: disabling


can you make a patch so i can test it using my own image?
Why not push it in lede? think less freq=less power consumation right ?


His patch is in his first post here: CPU frequency scaling driver for mvebu (WRT3200ACM etc.)
he described the method how to apply the patch here: CPU frequency scaling driver for mvebu (WRT3200ACM etc.)

dead easy :slight_smile:


@hnyman: seeing these as well, not sure if they are related to your patches:

Thu Apr 13 19:22:26 2017 kern.err kernel: [    1.219320] of: dev_pm_opp_of_cpumask_add_table: couldn't find opp table for cpu:0, -19
Thu Apr 13 19:22:26 2017 kern.err kernel: [    1.227374] cpu cpu1: opp_list_debug_create_link: Failed to create link
Thu Apr 13 19:22:26 2017 kern.err kernel: [    1.234023] cpu cpu1: _add_opp_dev: Failed to register opp debugfs (-12)


This is new...

Deprecated things appear in every boot from kernel 4.4


Do you have one of these gadgets which measure electricity consumption -- has it been improved by your patch? I'm waiting for a better binary for WiFi driver for WRT3200ACM before I can migrate to it and test your patch, I just can't run two routers at the same time right now.


@stangri: I don't think the power consumption is really that much less.

some feedback from my side: have been running for a little over 24 hours now, and it works perfectly fine.
usually it sticks to 800mhz, unless i do something really CPU-intensive like moving large files to the USB-attached harddrive, or running openSSL benchmarks.


I have some problems with all wifi radios.
After set the LED configuration for 2.4GHz and 5.0GHz all radios lost signal. Even showing the radios as active in LuCi interface.

Build: lede-r3910-20e40db524


Known bug in wrt1900ac/wrt1200ac/wrt3200acm series that wifi LEDs do not work. Has nothing to do with CPU frequency scaling.


I have uploaded a new test build for WRT3200ACM that contains also the new beta wifi driver release today at Kaloz repo.



I will test the new build... Anyone tested yet? Any reports?


I have naturally flashed it to my own router and it seems to work ok.

And I found also a nice surprise:
the new wifi driver 20170421 makes the wifi LEDs to finally work. I have no wifi LED configuration in /etc/config/system, but wifi LEDs properly blink with wifi activity. They are initially dark, but once there is traffic they start to blink and stay lit. ("wifi down" turns LEDs off, "wifi up" does not turn them initially on, but the subsequent traffic makes them to blink again and then they remain lit.)