Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Architectures & Platforms Gentoo on AMD64
  • Search

Undervolting with kernel 2.6 [Done!]

Have an x86-64 problem? Post here.
Locked
Advanced search
180 posts
  • Page 1 of 8
    • Jump to page:
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 8
  • Next
Author
Message
Fran
Guru
Guru
User avatar
Posts: 530
Joined: Sun Feb 29, 2004 3:14 pm
Location: Coruña (Spain)

Undervolting with kernel 2.6 [Done!]

  • Quote

Post by Fran » Sun Oct 31, 2004 4:13 pm

I used to have my athlon 64 undervolted to 1.4V with kernel 2.6.8, which was nice because with the cpu fan at 1400rpm (zero noise) the max temp was 53ºC at full load. With that kernel, when I switched the cpu governor to powersave and then back to performance, the undervolting was gone and the cpu went to default 1.5V, but at least I could have my cpu at 1.4 when I booted (or if I didn't change the governor).

But since 2.6.9, the cpu voltage is ALWAYS set at 1.5V when the frequency is 2.2GHz, no matter what I select in the bios. That forces me to increase the fan speed up to 2500rpm everytime I compile something , if I don't want the temp to exceed 63ºC :evil:.

I tried setting the default governor to userspace and performance, but that didn't help. I also tried removing the "ondemand" governor (the only visible difference between 2.6.8 and 2.6.9 in cpufreq), but it didn't help either.

Is there any way to choose the voltage of the CPU when it is put at max freq?

Thanks.

(edit) I've been investigating and I suposse that I can set manually the voltage table patching powernow-k8.c... but... it's scary :oops:.

(edit again) Done! :D. I modified powernow-k8.c and now my frequencies and voltages are:

2.2GHz ---> 1.4V
1.8GHz ---> 1.3V
1.0GHz ---> 1.0V

Even with the "ondemand" governor :D
Last edited by Fran on Tue Jan 24, 2006 8:23 pm, edited 1 time in total.
Top
brihall
Tux's lil' helper
Tux's lil' helper
Posts: 86
Joined: Tue Apr 29, 2003 8:56 pm
Location: Colorado, USA
Contact:
Contact brihall
Website

  • Quote

Post by brihall » Mon Nov 01, 2004 7:24 pm

Could you post (or give a link to) your modified powernow-k8.c? A patch would be nice. Even nicer, would be a way to set these voltage values via a /sys interface!
Top
Fran
Guru
Guru
User avatar
Posts: 530
Joined: Sun Feb 29, 2004 3:14 pm
Location: Coruña (Spain)

  • Quote

Post by Fran » Mon Nov 01, 2004 9:38 pm

My modified version is here ;). I only added one line, changing the value of data->powernow_table[0].index, which is read from the bios, to the value I'm interested in. The voltage set (in mV) by the kernel for each frequency is calculated as 1550-(data->powernow_table[j].index >> 8)*25. The default value read from the bios for 2.2GHz is (2 << 8), so we obtain 1550-2*25=1500. In my case, I want 1.4V for the highest freq. By adding (4 << 8) to that value we obtain 1550-6*25=1400mV.

If you want to try with lower voltages (1.375 or 1.35, for example), you can respectively use (5 << 8) or (6 << 8) instead of (4 << 8) ;).

Of course you can also change the voltages for 1.8GHz (data->powernow_table[1].index) and for 1GHz (data->powernow_table[2].index) if you want.

And of course you can find a better place for changing the value (for example, in the place where the values are read from the bios) or just change the value for (6 << 8) instead of adding (4 << 8)... but this is the first thing I tried, it worked, and you know... if it works, don't touch it :P.

The patch (edit: for 2.6.11):

Code: Select all

*** powernow-k8.c       2005-03-05 16:21:02.000000000 +0100
--- powernow-k8.c       2005-03-05 16:44:54.000000000 +0100
***************
*** 522,527 ****
--- 522,529 ----
  static void print_basics(struct powernow_k8_data *data)
  {
        int j;
+       if (data->numps >= 0)
+               data->powernow_table[0].index = data->powernow_table[0].index + (4 << 8);
        for (j = 0; j < data->numps; j++) {
                if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID)
                        printk(KERN_INFO PFX "   %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)\n", j,
I suppose I don't need to say it but: use this UNDER YOUR OWN RESPONSABILITY :). Anyway, there should be no danger if you understand what you're doing. I've been using it since yesterday and works great :D.

(edited to correct a little thing)
Last edited by Fran on Sun Mar 13, 2005 3:03 pm, edited 1 time in total.
Top
brihall
Tux's lil' helper
Tux's lil' helper
Posts: 86
Joined: Tue Apr 29, 2003 8:56 pm
Location: Colorado, USA
Contact:
Contact brihall
Website

  • Quote

Post by brihall » Sat Jan 22, 2005 2:27 am

OK, here's my version of the patch. After browsing the 'net for "undervoltage testimonials", I determined that the largest, safest undervolt was the following set (for a CG 3000+ 2GHz .13 micron chip):

2000 MHz 1.300 V
1800 MHz 1.200 V
1000 MHz 0.800 V

I have been running with these values for the past hour, emerging 11 packages while running foldingathome with asm options enabled and make -j3 kernel compiles. No problems whatsoever.

I did run the CPU fanless while doing these loading tests, but the max temp of 63C seemed too high to me. With the stock CPU HSF @ 5V I max out at 40C! Mid-tower steel case, 1 80mm PSU + 1 120mm exhaust.

The patch:

Code: Select all

--- /usr/src/linux/arch/i386/kernel/cpu/cpufreq/powernow-k8.c   2004-12-04 17:55:37.000000000 -0700
+++ powernow-k8-bwh.c   2005-01-21 18:21:39.741467104 -0700
@@ -516,7 +516,10 @@

 static void print_basics(struct powernow_k8_data *data)
 {
-       int j;
+        data->powernow_table[0].index =        data->powernow_table[0].index | 0x1c00; // 0.800V
+       data->powernow_table[1].index = data->powernow_table[1].index | 0x0e00; // 1.200V
+       data->powernow_table[2].index = data->powernow_table[2].index | 0x0a00; // 1.300V
+        int j;
        for (j = 0; j < data->numps; j++) {
                if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID)
                        printk(KERN_INFO PFX "   %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)\n", j,
@@ -577,6 +580,7 @@
        dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
        data->powernow_table = powernow_table;
        print_basics(data);
+       return 0; /* allow override of VID values in print_basics() */

        for (j = 0; j < data->numps; j++)
                if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid))
Top
tnt
Veteran
Veteran
User avatar
Posts: 1231
Joined: Fri Feb 27, 2004 11:57 pm

  • Quote

Post by tnt » Sat Mar 12, 2005 10:50 pm

+ data->powernow_table[0].index = data->powernow_table[0].index | 0x1c00; // 0.800V
I guess this is 0.850V...
gentoo user
Top
brihall
Tux's lil' helper
Tux's lil' helper
Posts: 86
Joined: Tue Apr 29, 2003 8:56 pm
Location: Colorado, USA
Contact:
Contact brihall
Website

  • Quote

Post by brihall » Sat Mar 12, 2005 11:25 pm

Yes, it was. Here's a slightly updated version of the patch. I had a lockup while idle that I attributed to the lower voltage, so I've raised the minimum to 0.90V. However, I have also been able to lower the voltage required for max speed stable operation. For standard desktop usage patterns, the idle voltage is important for overall power consumption, and the max speed voltage has more of an impact on temperature.

(2.6.11-ck2 kernel, 24x7)

cat /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
1000000 488407955
1800000 10515447
2000000 14432428


--- arch/i386/kernel/cpu/cpufreq/powernow-k8.c.orig 2005-03-02 00:38:10.000000000 -0700
+++ arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2005-03-06 16:07:55.000000000 -0700
@@ -521,7 +518,13 @@
static void print_basics(struct powernow_k8_data *data)
{
- int j;
+ data->powernow_table[0].index = data->powernow_table[0].index = 0x1a02; // 0.900V
+ data->powernow_table[1].index= data->powernow_table[1].index = 0x120a; // 1.100V
+ data->powernow_table[2].index= data->powernow_table[2].index = 0x0e0c; // 1.200V
+ int j;
for (j = 0; j < data->numps; j++) {
if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID)
printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)\n", j,
@@ -582,6 +585,7 @@
dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
data->powernow_table = powernow_table;
print_basics(data);
+ return 0; /* allow override of VID values in print_basics() */

for (j = 0; j < data->numps; j++)
if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid))
Top
ikaro
Advocate
Advocate
User avatar
Posts: 2527
Joined: Mon Jul 14, 2003 2:04 pm
Location: Denmark

  • Quote

Post by ikaro » Sun Mar 13, 2005 10:28 am

No patch needed.

o Go to the bios and set the default cpu volt to 1.3.
o use the ondemand governor
linux: #232767
Top
Fran
Guru
Guru
User avatar
Posts: 530
Joined: Sun Feb 29, 2004 3:14 pm
Location: Coruña (Spain)

  • Quote

Post by Fran » Sun Mar 13, 2005 3:02 pm

ikaro wrote:No patch needed.

o Go to the bios and set the default cpu volt to 1.3.
o use the ondemand governor
Maybe with your mobo and bios. Not with mine (MSI K8T NEO FSR with bios 1.7), since 2.6.9. I've always had 1.4V as the default voltage in the bios, and if I forget the patch when I compile a new kernel, the voltage is set to 1.5.

BTW, this thread is from october, i'll edit it with the patch for 2.6.11 :).
Top
ikaro
Advocate
Advocate
User avatar
Posts: 2527
Joined: Mon Jul 14, 2003 2:04 pm
Location: Denmark

  • Quote

Post by ikaro » Sun Mar 13, 2005 3:52 pm

thats because the bios shows the wrong voltages.
so 1.5 its actually 1.4.. this is something I read at extremeOverclocking.com(? not sure about the name )
it just prevents you from overclocking too much, because you can still reach decent speeds if the cooling is good.
linux: #232767
Top
Fran
Guru
Guru
User avatar
Posts: 530
Joined: Sun Feb 29, 2004 3:14 pm
Location: Coruña (Spain)

  • Quote

Post by Fran » Sun Mar 13, 2005 4:50 pm

Mmm... I don't understand very well what you mean... but I have an external tempreature sensor and I do notice the huge difference in temperatures (almost 10º at full load) when it's at 1.5V or at 1.4V. The sensor can't lie. And if I set the voltage in the bios at 1.4 and boot windows, the voltage is kept at 1.4, the temperature sensor confirms it. So it's a kernel problem.
Top
tnt
Veteran
Veteran
User avatar
Posts: 1231
Joined: Fri Feb 27, 2004 11:57 pm

  • Quote

Post by tnt » Sun Mar 13, 2005 10:47 pm

ikaro wrote:No patch needed.

o Go to the bios and set the default cpu volt to 1.3.
o use the ondemand governor
BIOS settings do not affect C'n'Q (powernow-k8) because multipliers and voltages for it are read from table later stored in:

data->powernow_table[x].index

and they override values manualy set in BIOS.
So, the only way to instruct kernel to set some other voltage then default (for that CPU state) is to modify values in that table.

:)
gentoo user
Top
Jtb
Apprentice
Apprentice
Posts: 157
Joined: Fri Dec 19, 2003 10:18 pm
Location: Germany/Darmstadt
Contact:
Contact Jtb
Website

  • Quote

Post by Jtb » Tue Apr 26, 2005 11:12 am

why do you change the voltage in static void print_basics?
Wouldn't it much better if you change them directly after reading them?
I change my voltage in powernow_k8_cpu_init_acpi and fill_powernow_table directly before "powernow_table.xy ="
Jens

.. God is real - unless declared integer!
Top
Fran
Guru
Guru
User avatar
Posts: 530
Joined: Sun Feb 29, 2004 3:14 pm
Location: Coruña (Spain)

  • Quote

Post by Fran » Tue Apr 26, 2005 11:46 am

Jtb wrote:why do you change the voltage in static void print_basics?
Wouldn't it much better if you change them directly after reading them?
I change my voltage in powernow_k8_cpu_init_acpi and fill_powernow_table directly before "powernow_table.xy ="


When I made the patch the first time I didn't want to search through the whole code of powernow-k8.c to find a good place to change the voltages. So I put it in the first place I found that I knew it would pass at least once, and only once. As I said above:

And of course you can find a better place for changing the value (for example, in the place where the values are read from the bios) [...]... but this is the first thing I tried, it worked, and you know... if it works, don't touch it :P.


;).
Top
Jtb
Apprentice
Apprentice
Posts: 157
Joined: Fri Dec 19, 2003 10:18 pm
Location: Germany/Darmstadt
Contact:
Contact Jtb
Website

  • Quote

Post by Jtb » Tue Apr 26, 2005 12:30 pm

:)

What about creating a undervoltage-parameter for the powernow-k8-modul?
I'm no kernel-programmer but I seems simply to realize..
Jens

.. God is real - unless declared integer!
Top
servo888
Apprentice
Apprentice
User avatar
Posts: 293
Joined: Sun Feb 22, 2004 4:21 am

  • Quote

Post by servo888 » Tue Jan 24, 2006 12:57 am

How about the 2.6.15 kernel? Everything looks different...
www.garberdesign.com
"You need a Windows PC to listen to this music." -listen.com
Top
tnt
Veteran
Veteran
User avatar
Posts: 1231
Joined: Fri Feb 27, 2004 11:57 pm

  • Quote

Post by tnt » Tue Jan 24, 2006 1:09 am

I've made that hack last time on the 2.6.13, but as far as I can see there is no difference with 2.6.15 (just line numbering is somewhat shifted):

Code: Select all

diff powernow-k8.c.2.6.13 powernow-k8.c.2.6.13.original


537,538d536
<       data->powernow_table[0].index = data->powernow_table[0].index + (5 << 8); // 1.275V
<       data->powernow_table[1].index = data->powernow_table[1].index + (4 << 8); // 1.000V
599,601d596
<
<
<       return 0; /* allow override of VID values in print_basics() */
gentoo user
Top
Fran
Guru
Guru
User avatar
Posts: 530
Joined: Sun Feb 29, 2004 3:14 pm
Location: Coruña (Spain)

  • Quote

Post by Fran » Tue Jan 24, 2006 8:22 pm

servo888 wrote:How about the 2.6.15 kernel? Everything looks different...
Yeah, powernow-k8.c changes a little with every kernel version. But the lines you must add are the same. Just look for the proper location (print_basics or wherever you want to put them).

PS: This thread never dies :mrgreen:
Top
tnt
Veteran
Veteran
User avatar
Posts: 1231
Joined: Fri Feb 27, 2004 11:57 pm

  • Quote

Post by tnt » Wed Jan 25, 2006 1:13 am

Fran wrote:This thread never dies :mrgreen:
because it's so useful ;)
gentoo user
Top
Evangelion
Veteran
Veteran
User avatar
Posts: 1087
Joined: Fri May 31, 2002 8:53 am
Location: Helsinki, Finland

  • Quote

Post by Evangelion » Wed Jan 25, 2006 8:09 am

few questions:

a) why doesn't the powernow-module scale the voltage (like it should)?

b) where do you check the voltage of the CPU in a running system?
My tech-blog | My other blog
Top
quax
n00b
n00b
Posts: 3
Joined: Wed Oct 20, 2004 7:36 pm

  • Quote

Post by quax » Wed Jan 25, 2006 11:34 am

Fran wrote:

Code: Select all

*** powernow-k8.c       2005-03-05 16:21:02.000000000 +0100
--- powernow-k8.c       2005-03-05 16:44:54.000000000 +0100
***************
*** 522,527 ****
--- 522,529 ----
  static void print_basics(struct powernow_k8_data *data)
  {
        int j;
+       if (data->numps >= 0)
+               data->powernow_table[0].index = data->powernow_table[0].index + (4 << 8);
        for (j = 0; j < data->numps; j++) {
                if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID)
                        printk(KERN_INFO PFX "   %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)\n", j,
I think, better is to edit DSDT an overide old table with new via CONFIG_ACPI_CUSTOM_DSDT kernel config option.

You need add or modify _PSS method and others related methods (_PPC). Nice example is in the ACPI Specification v3.0 on pages 274 - 277.
Top
Fran
Guru
Guru
User avatar
Posts: 530
Joined: Sun Feb 29, 2004 3:14 pm
Location: Coruña (Spain)

  • Quote

Post by Fran » Wed Jan 25, 2006 2:46 pm

Evangelion wrote:a) why doesn't the powernow-module scale the voltage (like it should)?
powernow-k8 does scale the voltage, following a table that it reads from the bios. But if you want lower voltages than those in that table, you must patch the kernel.
Evangelion wrote:b) where do you check the voltage of the CPU in a running system?
You can try with lm-sensors, or simply look at /sys/bus/i2c/devices/*/in*_input. One of those files contains Vcore.
quax wrote:I think, better is to edit DSDT an overide old table with new via CONFIG_ACPI_CUSTOM_DSDT kernel config option.

You need add or modify _PSS method and others related methods (_PPC). Nice example is in the ACPI Specification v3.0 on pages 274 - 277.
Probably a more elegant solution, but it seems way more complicated (at least looking at the pdf, gentoo wiki is down right now).
Top
quax
n00b
n00b
Posts: 3
Joined: Wed Oct 20, 2004 7:36 pm

  • Quote

Post by quax » Wed Jan 25, 2006 3:47 pm

Fran wrote: powernow-k8 does scale the voltage, following a table that it reads from the bios. But if you want lower voltages than those in that table, you must patch the kernel.
Reading PST table from bios is deprecated, ACPI way is prefered. PST table supports only one CPU. powernow-k8 module read first APCI.
Fran wrote: Probably a more elegant solution, but it seems way more complicated (at least looking at the pdf, gentoo wiki is down right now).
My laptop have a buggy DSDT table (Acer Aspire 1511LMi) and I was spend too many hours with repairing this table and patching kernel with APCI from sf.net. Adding _PSS method isn't problem for me, but i don't know right values for the TransitionLatency, BusMasterLatency and Control parameters.
Top
tnt
Veteran
Veteran
User avatar
Posts: 1231
Joined: Fri Feb 27, 2004 11:57 pm

  • Quote

Post by tnt » Wed Jan 25, 2006 3:59 pm

cpufreq at lists dot linux dot org dot uk
gentoo user
Top
morfic
Retired Dev
Retired Dev
Posts: 31
Joined: Wed Jul 28, 2004 1:22 am

  • Quote

Post by morfic » Sun Feb 05, 2006 9:46 pm

please try the following patch if you would like the ability to change the voltage at boot time or whenever inserting powernow-k8 module

patch kernel 2.6.16-rc2 (only tested on vanilla) with this patch: http://dev.gentoo.org/~morfic/powernow- ... 6-rc2.diff

add powernow-k8.vcore_list=value1,value2,value3 to the kernel command line in grub or lilo

or build powernow-k8 as module and do 'modprobe powernow-k8 vcore_list=value1,value2,value3

please only specify any new voltages for each powernow-k8 step you have

dmesg | grep powernow will show current values/number of states you have

value is in millivolt, so to change from 1.3 to 1.1 you would specify 1100

i will now paste my dmesg to illustrate how this works on a turion64 with 2 states

morfic@localhost64 ~ $ dmesg | grep powernow
Bootdata ok (command line is root=/dev/hda7 vga=792 powernow-k8.vcore_list=1100,900)
Kernel command line: root=/dev/hda7 vga=792 powernow-k8.vcore_list=1100,900
powernow-k8: Found 1 AMD Athlon 64 / Opteron processors (version 1.60.0)
powernow-k8: Request Voltage for id0 is 1100 mV default voltage is 1450
powernow-k8: Performing required adjustment of 350 mV or 14 25mV steps
powernow-k8: Request Voltage for id1 is 900 mV default voltage is 1000
powernow-k8: Performing required adjustment of 100 mV or 4 25mV steps
powernow-k8: 0 : fid 0x8 (1600 MHz), vid 0x12 (1100 mV)
powernow-k8: 1 : fid 0x0 (800 MHz), vid 0x1a (900 mV)
powernow-k8: ph2 null fid transition 0x8
morfic@localhost64 ~ $

the ph2 line means we trigger a transition where the frequency has not changed

i have made the patch because calculating it was too cumbersome fr me and friends, aside my default voltage is 1.45V in linux while i used the spec of 1.5V so i was always off by .05V, the patch will adjust the voltage by the difference of currently read from bios from requested voltage, much more failsafe i think

as usual, neither i nor gentoo grant no guarantees and warrantees, use fhis patch is entirely at your own risk, improper use of this patch can lead to system instabilities and damage your hardware, by downloading the and applying the patch you acknowledge this.

i would appreciate user feedback, especially from people with 3 or more power states

note: the power usage in /proc/acpi/processor/cpu*/power is hardcoded and will not change when you lower your vcore
note: if you build powernow-k8 as module you will not automatically use your usual scaling governor, modprobe powernow-k8 and set your usual scaling governor
Top
morfic
Retired Dev
Retired Dev
Posts: 31
Joined: Wed Jul 28, 2004 1:22 am

  • Quote

Post by morfic » Sun Feb 05, 2006 9:54 pm

forgot to add, 1.45V@1600Mhz means 90C compiles
while 1.1V@1600MHz mean 60C compiles

hot little turion, i know
Top
Locked

180 posts
  • Page 1 of 8
    • Jump to page:
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 8
  • Next

Return to “Gentoo on AMD64”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Authors
Gentoo is a trademark of the Gentoo Foundation, Inc. and of Förderverein Gentoo e.V.
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-4.0 license.
The Gentoo Name and Logo Usage Guidelines apply.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy