Cpufreq

Basics
Since the main market for Allwinner are mobile devices it is one of the design goals of their SoCs to be able to operate both performant as well as energy efficient. An important role plays 'cpu frequency scaling'. The lower the clock speed, the slower the device and the less energy it consumes (and vice versa). Even the voltage available to the ARM core(s) will be adjusted depending on the clock speed: With older 3.4.x kernels this was done in U-Boot: there existed a mapping called dvfs_table between clock speeds and voltage. Now in mainline kernel this is done inside the kernel by defining similar operating-points (the higher the CPU is clocked the more voltage it needs to still operate reliable).

It's not enough to define a set of CPU frequency/voltage mappings and upper/lower limits but also strategies to switch between them are needed. These so called cpufreq governors are responsible for that. If your kernel supports cpu frequency scaling you can get the list of available governors and dvfs_table-mappings/operating-points by:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies

Possible adjustments
Out of the available governors the most interesting seem to be ondemand and interactive (the latter only available in kernel 3.4 but not with mainline any longer) since they dynamically switch cpufreq settings based on load. The default with mainline kernel is now ondemand (you can adjust that by writing to scaling_governor) and the lower/upper limits are 144000 and 960000 on sun7i (144MHz-960MHz -- back with kernel 3.4 the range was 60MHz-1008MHz instead). Since the default lower limit might be responsible for a laggy system (it takes quite a bit of time for the governor to realize that the frequency needs to be increased) it's advisable to define the lower limit yourself adjusting /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq eg.

echo 408000 >/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq

You can also lower the maximum value by adjusting scaling_max_freq. Please be aware that adjusting these values works in 48MHz steps and is not limited to the few operating-points/dvfs_table-entries. You can use any value in between min/max but have to keep in mind that the values supplied will be rounded down: you will end up with just 864MHz if you set scaling_max_freq to 911999 instead of 912000 -- always compare with cpuinfo_cur_freq if in doubt.

Performance/functionality impacts
Both the chosen governor as well as the cpufreq limits can have a huge impact on power consumption, performance and even functionality. For example in the past on sun7i (A20), the default fantasy governor led to really strange behaviour (and single-threaded benchmark results for A20 devices as well) since it increased the clock speed to the max value only under certain circumstances and remained most of the time at the minimum.

If you allow very low scaling_min_freq values with ondemand/interactive the system might behave laggy and some timing critical stuff (eg. reading out Dallas DS18b20 temperature sensors via 1-wire below 600MHz) won't work. Same applies to other sort of GPIO stuff when reaching the upper frequency limits (eg. reading out DHT11/DHT22 with scaling_max_freq above 1008MHz). So you've to carefully adjust the cpufreq settings to your application.

If you need maximum performance then using the governor with this name might be a good idea. But since then the CPU core(s) will always be clocked at the upper limit (speed/voltage) it's better to use ondemand with reasonable settings if you only need peak performance from time to time. A good compromise between power consumption and a responsive system being able to operate at full performance when needed is


 * 1) !/bin/sh

echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

echo 1008000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq echo 408000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq

echo 25 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold echo 10 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor echo 1 > /sys/devices/system/cpu/cpufreq/ondemand/io_is_busy

(can also be used with kernel 4.0 and above. And especially io_is_busy is essential if you want to use your sunxi device as file server). The other parameters are explained in the governor link above. Adjust them only carefully without a full understanding what you're doing.

"Overclocking"
As per the definition of the word "overclocking" is not possible since that would mean "frequency scaling beyond the specs". The problem with cheap ARM SoCs is that they're not subject to an expensive QA/selection process where each SoC will be tested extensively and then labeled/sold in different categories depending on the upper limits it's able to achieve (this is standard with x86 for example: chips from the same wafer will be tested individually and be sold for a few hundred bucks more or less depending on how many CPU/GPU cores work reliable at which clock speeds).

One A20 SoC from a specific production batch might work reliable with 1.4GHz while another starts to throw errors with 1.0GHz. The default cpufreq upper limits take that into account and can be considered sane/safe defaults. And while it's possible to adjust or define additional operating-points in the kernel sources to gain some more speed (with increased voltage) this should be considered experimental and is only advisable when you the user also does QA/selection on your own: Stresstesting the device over many hours to simulate worst case conditions while keeping an eye on heat dissipation: Without appropriate airflow increasing cpufreq settings above defaults won't work.