Fun With Linux Cpufreq Driver
Have you ever used a computer with the (famous) turbo button? Some PCs, usually XT clones with a 10MHz 8088 processor (16-bit core, 8-bit bus), included a turbo button that changed speed from the "compatible" 4.77 MHz to the "fast" 10MHz. Although practically useless, since it was usually stuck to "high", its existence was nevertheless quite intriguing.
Now you can have the same kind of fun with your desktop processor by changing its speed at will. All you need is a recent Linux kernel and a supported processor. Version 2.6 should do fine, although only 2.6.10 and later worked for my Asus K8V Bios 1.007b + Athlon 64. Supported processors are (as of version 188.8.131.52) :
--- CPUFreq processor drivers
- ACPI Processor P-States driver (generic, may work)
- AMD Mobile K6-2/K6-3 PowerNow! (mobile, rare cpu)
- AMD Mobile Athlon/Duron PowerNow! (mobile)
- AMD Opteron/Athlon64 PowerNow!
- Cyrix MediaGX/NatSemi Geode Suspend Modulation
- Intel Enhanced SpeedStep
- Intel Speedstep on ICH-M chipsets (ioport interface)
- Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)
- Intel Pentium 4 clock modulation
- nVidia nForce2 FSB changing
- Transmeta LongRun
- VIA Cyrix III Longhaul
- Enable a relevant BIOS option, if necessary. In my case, I had to enable Cool'n'Quiet for the Athlon 64. Some older BIOSes may be buggy, but check before doing an unnecessary BIOS upgrade.
- Enable the "cpufreq" driver under "Power Management" in the Linux kernel configuration.
- Choose your CPU from the list of drivers
- Choose a "cpu frequency governor" that tells the kernel when to change frequency.
- Recompile and boot
- Go to /sys/devices/system/cpu/cpu0/cpufreq and try the various options.
Default CPUFreq governor (performance)
- --- 'performance' governor : fastest speed and highest power, unless you manually override it
- <*> 'powersave' governor: slowest speed and lowest power, unless you manually override it
- <*> 'userspace' governor for userspace frequency scaling: a user-space program (daemon) uses more complicated "rules" and "policies" to ensure optimal behavior. This is a complex solution that is most appropriate for notebooks or when very precise control of frequency scaling is needed.
- <*> 'ondemand' cpufreq policy governor : tries to use the slowest speed as much as possible, but quickly switches up or down when needed
- <*> 'conservative' cpufreq governor : tries to use the slowest speed as much as possible and is more reluctant to change speeds (either from high to low, or the opposite).
Note that I have checked (included in the kernel) all governors. You can choose any of them at run time and it doesn't hurt to have them around.
If you have done all the above correctly then after reboot you should see something like (may vary depending on the actual processor, of course):
powernow-k8: Found 1 AMD Athlon 64 / Opteron processors (version 1.00.09e)
powernow-k8: 0 : fid 0xe (2200 MHz), vid 0x2 (1500 mV)
powernow-k8: 1 : fid 0xc (2000 MHz), vid 0x6 (1400 mV)
powernow-k8: 2 : fid 0xa (1800 MHz), vid 0xa (1300 mV)
powernow-k8: 3 : fid 0x2 (1000 MHz), vid 0x12 (1100 mV)
cpu_init done, current fid 0xe, vid 0x2
This message appears after the network initialization and before the ACPI initialization on my computer. You may review kernel boot messages with "dmesg | less".
Here we see that the processor is currently at 2200MHz (0xe fid) and 1500mV (0x2 vid).
We should now see a directory : "/sys/devices/system/cpu/cpu0/cpufreq/" (similarly for cpu1, cpu2 etc)
cat scaling_available_governors # lists available governors
echo powersave >scaling_governor # set minimum speed
echo performance >scaling_governor # set maximum speed
You may also try:
cat scaling_max_freq # show max speed
cat scaling_min_freq # show minimum speed
cat scaling_cur_freq # show current speed
Minimum and maximum can also be manually set (within the preset cpu limits, of course) so that speed never goes above or below a certain point.
echo 1800000 >scaling_max_freq # Maximum speed that we want to use is 1.8GHz
echo 1500000 >scaling_min_freq # Minimum speed that we want to use is 1.5GHz
The frequency must be in KHz. You cannot write "echo 3.2 >scaling_max_freq". You must use "echo 3200000>scaling_max_freq" instead.
Now try "cat /proc/cpuinfo" and see your current speed!!
If you want automatic speed changing you can try the "ondemand" governor. It works quite well, but for some cpus, especially Athlon64, the "conservative" governor might be better. In my experience, the conservative governor hesitates a lot before changing speeds.
As an example, right now my processor "idles" at 1000Mhz, 1.1V. This lowers power consumption significantly. If I want to play a game or compress some music I can easily increase its performance or let the "ondemand" governor do it automatically. This is a great trick, and everyone should try it!!
Note: this does not constitute overclocking and should not pose a danger to your cpu in any way. Appropriate frequency switching is a great way to reduce heat dissipation and power consumption when you are doing tasks that are not cpu-intensive. That being said, however, I do not assume any responsibility if you decide to try this.