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 with kernel 4.9, 4.14, 4.19 and currently with 5.4.

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.

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 5.4

as a 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 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, as shown in commit:

I have adapted the driver first for kernel 4.9, then for 4.14, 4.19 and 5.4. 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.

I haven't really compared this to the upstream changes in between, but the code runs ok with kernel 5.4.

Run-tested with WRT3200ACM (Armada 385) at master r14966-7330348f2d

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


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.


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

1 Like

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)

1 Like

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.)