[KERNEL] Undervolt driver for the stock HTC kernel for Desire and others (2.6.32.15)

Search This thread

iscaela

Senior Member
Aug 31, 2010
65
14
This kernel module allows you to run any official Froyo kernel image from HTC with reduced CPU voltages at each frequency. Reducing voltage decreases the power consumed by the CPU (dissipated as heat).

INSTALL:
You need root or an unrestricted recovery image (e.g ClockworkMod) to install this. The default settings decrease voltage by 75-100 mV which seems stable on my device. Just download the attached file and select it from recovery or ROM Manager.

I've built "update.zip" files for the Desire with Linux kernel versions 2.6.32.15-gf9c0527, 2.6.32.15-gd96f2c0, and 2.6.32.15-g6a358a9. You can check your kernel version in Settings->About phone->Software information.

Other HTC devices running Froyo are supported. If you have a different device, please give me the full version number and I can add an update.zip for it.


Undervolt driver for the EVO 4G



Added undervolt-2.6.32.15-gd96f2c0-20100907.zip.
Added undervolt-2.6.32.15-g6a358a9-20100907.zip.
Added undervolt-2.6.32.15-gf5a401c-20100907.zip.


USAGE:
Read the instructions above first. If you are happy with the default settings, you don't need to read this unless you're curious


To load the driver, use an init script like this one (included):
Code:
#!/system/bin/sh
#
# Load undervolt for htc-kernel
addr=`awk '$3 == "acpuclk_set_rate" { print "0x"$1; }' /proc/kallsyms`
if [ -n "$addr" ]; then
        insmod /system/lib/modules/undervolt.ko "acpuclk_set_rate_addr=$addr"
        if [ $? -eq 0 ]; then
                echo '-75' > /proc/undervolt
                echo '1225 1125' > /proc/undervolt
                echo '1250 1150' > /proc/undervolt
                echo '1275 1175' > /proc/undervolt
                echo '1300 1200' > /proc/undervolt
                echo '1' > /proc/undervolt
                echo "+++ undervolt enabled"
                exit 0
        fi      
fi
echo "+++ undervolt could not be enabled

The driver adds a "/proc/undervolt" knob to make voltage changes, reading from it prints the current default and adjusted voltages in mV for every CPU frequency, e.g.:
Code:
cat /proc/undervolt
1050  975    19200
1050  975   128000
...
1300 1200   960000
1300 1200   998400
Write a space-separated pair of default and adjusted voltages in mV to change the values in the table, e.g. to undervolt stock freqs using 1500 mV to 1000mV):
Code:
echo '1050 1000' > /proc/undervolt
.
Write '+' or '-' followed by a single number to adjust *all* voltages by that amount in mV:
Code:
echo '-25' > /proc/undervolt
The changes are NOT applied until you write the number 1:
Code:
echo '1' > /proc/undervolt
Writing the number 0 reverts all voltages to the default. This also happens when you unload the module with rmmod.

BACKGROUND:
I figured it would be possible to locate and modify acpu_freq_tbl on the stock HTC kernel with a LKM (since /dev/kmem isn't available), and I was right, although it involved peeking at the ARM opcodes. The method should also work for other HTC kernel images on recent devices (anything with a "Scorpion" CPU): Nexus One, Droid Incredible, EVO 4G. Overclocking will be possible with a bit more work.

This also disables the voltage constraints set by the board-specific configuration (e.g. in board-bravo.c or board-incrediblec.c). This was done by y patching the regulator_set_voltage function to simply ignore the constraints. The remaining limits are imposed by the driver for the regulator IC. The TPS65023 driver defines these for VDCDC1: min_uV = 800000, max_uV = 1600000.

KNOWN BUGS:
There is a vdd_undervolt parameter to set the default undervolt, but it is ignored (by insmod?), use +/- instead.
 

Attachments

  • undervolt-2.6.32.15-gf9c0527-20100907.zip
    6 KB · Views: 1,077
  • undervolt.c.txt
    12.1 KB · Views: 767
  • undervolt-2.6.32.15-gd96f2c0-20100907.zip
    6 KB · Views: 448
  • undervolt-2.6.32.15-g6a358a9-20100907.zip
    6 KB · Views: 271
  • undervolt-2.6.32.15-gf5a401c-20100907.zip
    6 KB · Views: 227
Last edited:
  • Like
Reactions: hell_lock

ieftm

Retired Recognized Developer
Apr 17, 2008
291
1,761
That is, in fact, fantastic work :)

Of course it will be obsoleted when HTC decides to release their source but you know that :)

I assume you verified these actually work?
 

ieftm

Retired Recognized Developer
Apr 17, 2008
291
1,761
Did you account for the fact the stock kernel has board files to constrain the minimum
and maximum voltage?

eg, board-bravo.c:
.min_uV = 1000000
.max_uV = 1300000

The same goes for overclocking, the upper limit for the clock is set, hardcoded,
so you would need to change that as well.
 

iscaela

Senior Member
Aug 31, 2010
65
14
Did you account for the fact the stock kernel has board files to constrain the minimum
and maximum voltage?

eg, board-bravo.c:
.min_uV = 1000000
.max_uV = 1300000

The same goes for overclocking, the upper limit for the clock is set, hardcoded,
so you would need to change that as well.
Yikes, I didn't know about that, is that in bravo_fixup (which I hope is in the .init section like acpu_freq_tbl_fixup)? Is board-bravo.c in the incrediblec or vanilla Android kernel trees? I'm using the supersonic source atm.

Thanks!

-Albert
 

iscaela

Senior Member
Aug 31, 2010
65
14
That is, in fact, fantastic work :)

Of course it will be obsoleted when HTC decides to release their source but you know that :)

I assume you verified these actually work?
Thanks, I haven't hacked on the Linux kernel in ages and wasted a lot of time targeting acpu_freq_tbl_fixup originally (as you might have noticed in the comments).

The idea is that this should work with the stock kernel images of multiple devices without reflashing, and in future releases with only minor changes.

I didn't take a multimeter to the board, if that's what you mean... but acpu_freq_tbl is canonical list of voltages (unless something in board-bravo.c rewrites it after initialisation, which seems unlikely) and this is able to read and write to the table. The actual CPU frequencies are duplicated in another structure (which is why I haven't tried overclocking yet) but the voltages are read directly from the table and scaled to microvolts for the governor.
 

knights191

Senior Member
Mar 1, 2008
213
0
Thanks alot for your work. Does anybody have ' proof ' this script works on a Desire running standard HTC Froyo ?

There is no way to check is there, except having better battery life?
What kind of energy saving is possible with this method?

Thanks :)
 

knights191

Senior Member
Mar 1, 2008
213
0
Ne0, you are on the Dutch television as we speak (the matrix revolutions)

At what mV is the desire standard doing ? Going to flash you 7.6 now :)
 

iscaela

Senior Member
Aug 31, 2010
65
14
UPDATED 2010-09-07
This also disables the voltage constraints set by the board-specific configuration (e.g. in board-bravo.c or board-incrediblec.c). This was done by y patching the regulator_set_voltage function to simply ignore the constraints. The remaining limits are imposed by the driver for the regulator IC. The TPS65023 driver defines these for VDCDC1: min_uV = 800000, max_uV = 1600000. I'll probably work on overclocking next.

Thanks for the advice, folks. I've confirmed that the voltage changes are pushed to the regulator (the previous version had trouble applying table changes sometimes, but the regulator code would print a message when you exceeded the board configuration voltage constraints).

Are there other kernel versions or devices people want me to support? It's mostly a matter of changing the vermagic string in the file at this point.
 
thanks, installed on R8 Paul's (Modaco) ROM kernel 2.6.32.15-gf9c0527
it's working!

# uname -r
2.6.32.15-gf9c0527
# lsmod
tun 10734 0 - Live 0xbf049000
bcm4329 202947 0 - Live 0xbf015000
cpufreq_powersave 668 1 - Live 0xbf012000
cpufreq_interactive 2368 0 - Live 0xbf00c000
undervolt 2644 0 - Live 0xbf006000
perflock_disable 752 0 - Live 0xbf000000
# cat /proc/undervolt
1050 975 19200
1050 975 128000
1050 975 245000
1050 975 384000
1050 975 422400
1050 975 460800
1075 1000 499200
1100 1025 537600
1100 1025 576000
1125 1050 614400
1150 1075 652800
1175 1100 691200
1200 1125 729600
1200 1125 768000
1225 1125 806400
1250 1150 844800
1275 1175 883200
1300 1200 921600
1300 1200 960000
1300 1200 998400

# echo '-25' > /proc/undervolt
# echo '1' > /proc/undervolt
# cat /proc/undervolt
1050 925 19200
1050 925 128000
1050 925 245000
1050 925 384000
1050 925 422400
1050 925 460800
1075 950 499200
1100 975 537600
1100 975 576000
1125 1000 614400
1150 1025 652800
1175 1050 691200
1200 1075 729600
1200 1075 768000
1225 1075 806400
1250 1100 844800
1275 1125 883200
1300 1150 921600
1300 1150 960000
1300 1150 998400

# echo '-25' > /proc/undervolt
# cat /proc/undervolt
1050 900 19200
1050 900 128000
1050 900 245000
1050 900 384000
1050 900 422400
1050 900 460800
1075 925 499200
1100 950 537600
1100 950 576000
1125 975 614400
1150 1000 652800
1175 1025 691200
1200 1050 729600
1200 1050 768000
1225 1050 806400
1250 1075 844800
1275 1100 883200
1300 1125 921600
1300 1125 960000
1300 1125 998400
 
Last edited:

NeoPhyTe.x360

Retired Recognized Developer
Aug 20, 2009
1,667
1,850
oυτ oƒ иoωнєяє
ANY value on ANY freq below 1000mV freezes device so, min value still being 1000mV

If you put any value below 1000 in init script, at my case, device freezes when load with -1.
 

ouglouck

Senior Member
Aug 1, 2010
383
47
Khazad-dûm
This driver allows you to run any stock Froyo HTC Linux kernel with lowered CPU voltages. It modifies the voltage table at runtime.

I've built update.zip files for the Desire 2.6.32.15-gf9c0527 and 2.6.32.15-gd96f2c0 that applies a 75-100 mV undervolt which seems stable for me. Just download and install the files in recovery.

What can we expect from that modification ?

A lower heat of the processor (not sure regarding the difference) and a longer battery life ?

If I read that correctly, looks as a very interesting stuff.

(might be a stupid question, if so apologize)

Thank you.
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 1
    This kernel module allows you to run any official Froyo kernel image from HTC with reduced CPU voltages at each frequency. Reducing voltage decreases the power consumed by the CPU (dissipated as heat).

    INSTALL:
    You need root or an unrestricted recovery image (e.g ClockworkMod) to install this. The default settings decrease voltage by 75-100 mV which seems stable on my device. Just download the attached file and select it from recovery or ROM Manager.

    I've built "update.zip" files for the Desire with Linux kernel versions 2.6.32.15-gf9c0527, 2.6.32.15-gd96f2c0, and 2.6.32.15-g6a358a9. You can check your kernel version in Settings->About phone->Software information.

    Other HTC devices running Froyo are supported. If you have a different device, please give me the full version number and I can add an update.zip for it.


    Undervolt driver for the EVO 4G



    Added undervolt-2.6.32.15-gd96f2c0-20100907.zip.
    Added undervolt-2.6.32.15-g6a358a9-20100907.zip.
    Added undervolt-2.6.32.15-gf5a401c-20100907.zip.


    USAGE:
    Read the instructions above first. If you are happy with the default settings, you don't need to read this unless you're curious


    To load the driver, use an init script like this one (included):
    Code:
    #!/system/bin/sh
    #
    # Load undervolt for htc-kernel
    addr=`awk '$3 == "acpuclk_set_rate" { print "0x"$1; }' /proc/kallsyms`
    if [ -n "$addr" ]; then
            insmod /system/lib/modules/undervolt.ko "acpuclk_set_rate_addr=$addr"
            if [ $? -eq 0 ]; then
                    echo '-75' > /proc/undervolt
                    echo '1225 1125' > /proc/undervolt
                    echo '1250 1150' > /proc/undervolt
                    echo '1275 1175' > /proc/undervolt
                    echo '1300 1200' > /proc/undervolt
                    echo '1' > /proc/undervolt
                    echo "+++ undervolt enabled"
                    exit 0
            fi      
    fi
    echo "+++ undervolt could not be enabled

    The driver adds a "/proc/undervolt" knob to make voltage changes, reading from it prints the current default and adjusted voltages in mV for every CPU frequency, e.g.:
    Code:
    cat /proc/undervolt
    1050  975    19200
    1050  975   128000
    ...
    1300 1200   960000
    1300 1200   998400
    Write a space-separated pair of default and adjusted voltages in mV to change the values in the table, e.g. to undervolt stock freqs using 1500 mV to 1000mV):
    Code:
    echo '1050 1000' > /proc/undervolt
    .
    Write '+' or '-' followed by a single number to adjust *all* voltages by that amount in mV:
    Code:
    echo '-25' > /proc/undervolt
    The changes are NOT applied until you write the number 1:
    Code:
    echo '1' > /proc/undervolt
    Writing the number 0 reverts all voltages to the default. This also happens when you unload the module with rmmod.

    BACKGROUND:
    I figured it would be possible to locate and modify acpu_freq_tbl on the stock HTC kernel with a LKM (since /dev/kmem isn't available), and I was right, although it involved peeking at the ARM opcodes. The method should also work for other HTC kernel images on recent devices (anything with a "Scorpion" CPU): Nexus One, Droid Incredible, EVO 4G. Overclocking will be possible with a bit more work.

    This also disables the voltage constraints set by the board-specific configuration (e.g. in board-bravo.c or board-incrediblec.c). This was done by y patching the regulator_set_voltage function to simply ignore the constraints. The remaining limits are imposed by the driver for the regulator IC. The TPS65023 driver defines these for VDCDC1: min_uV = 800000, max_uV = 1600000.

    KNOWN BUGS:
    There is a vdd_undervolt parameter to set the default undervolt, but it is ignored (by insmod?), use +/- instead.