# Undervolt Hacking powernow-k8.c

## Cyker

Hi!

I want to hack in a 200mV voltage decrease across the board into the powernow-k8.c

I've worked out that I need to add 0x8 to all the values to get this decrease, but I'm not sure where in the powernow-k8.c would be the best place.

There are a couple of loops like this in the file:

```
        for (j = 0; j < data->numps; j++) {

                powernow_table[j].index = pst[j].fid; /* lower 8 bits */

                powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */

                powernow_table[j].frequency = find_khz_freq_from_fid(pst[j].fid)

        }
```

I figure I just need to do something like:

```
powernow_table[j].index |= ( (pst[j].vid  + 0x8) << 8); /* upper 8 bits */
```

 ... to get what I want, but the problem is which one of the loops do I put it in?!

Or is there in fact a better place I should put it in?

I can't read driver code because they don't have a single entrypoint, but I need to make sure wherever I put the modifications in, it only gets executed once, but sticks!

Paranoia stops me from just trying this out without making damned sure I'll do it right - Measure twice and cut once and all that.(And also, I only have one of these CPUs and I don't want to let the magic smoke out of it  :Wink: )

There have been some other threads regarding this in the AMD64 section, but they reference patches and diffs that no longer seem to exist...

----------

## Cyker

Aww, not even a little hint?  :Crying or Very sad:   :Mr. Green: 

----------

## Cyker

Well, it looks like the two most likely candidates are in the:

fill_powernow_table()

and the

fill_powernow_table_fidvid()

functions.

The top one seems to be for standard Powernow, while the other is for ACPI pstates.

I don't know what that means!

Which one does the Athlon 64 X2 use?!

Can I put the hacks into both safely?

Questions questions...

----------

## tnt

this is diff for 1.0V and 1.275V (kernel 2.6.20) used for athlon64 3000+ (winchester core) running at 1 and 1.8GHz (default 1.1 and 1.4V):

```

598a599,600

>       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

665a668,670

>       return 0; /* allow override of VID values in print_basics() */

> 
```

----------

## Cyker

Well my kludges seem to be working okay, but now I be wanting some more fine-grained control over the voltages! (Esp. since I'm getting MCE CPU cache bit errors at higher freqs when running CFD simulations!  :Shocked: )

So, under fill_powernow_table() and fill_powernow_table_fidvid()

inside the "for (j = 0; j < data->numps; j++)" loop, I'm going to stick some code that will look something like this:

```
// Start of dirty dirty hack

if( pst[j].fid == 0x10 )  powernow_table[j].index |= ( 0xC <<8 );

if( pst[j].fid == 0xE )  powernow_table[j].index |= ( 0xE <<8 );

if( pst[j].fid == 0xC )  powernow_table[j].index |= ( 0x12 <<8 );

if( pst[j].fid == 0xA )  powernow_table[j].index |= ( 0x14 <<8 );

if( pst[j].fid == 0x2 )  powernow_table[j].index |= ( 0x19 <<8 );

/*

fid=0x10(2400MHz), vid=0xc(1250mV)

fid=0xe(2200MHz), vid=0xe(1200mV)

fid=0xc(2000MHz), vid=0x12(1100mV)

fid=0xa(1800MHz), vid=0x14(1050mV)

fid=0x2(1000MHz), vid=0x19(925mV)

*/

//End of hack

```

If anyone can see some obvious problems with this, I'd welcome the heads up!  :Smile: 

The code fragment is adapted from the patch at http://www.i-hasser.net/host_linux/powernow_k8.patch.gz

----------

