[PATCH] powernow-k7 settling time

From: Jens David
Date: Tue Jan 13 2004 - 17:46:25 EST


Hi Dave, Jeff & all,

I do not know exactly where to send this patch to, so please
forward as appropriate.

This patch is needed to get powernow-k7 to work on my el-cheapo
notebook. It seems that the BIOS table that describes the voltage
regulator settling time and possible frequency/clock combinations
is buggy in some cases (such as mine). Specifically if the settling
time is not large enough we switch clock frequencies too soon,
resulting in system instability and possible hardware damage.
This patch analyzes the value suggested by the BIOS and if too
low (I do not believe any general-purpose high current CPU VR
design will settle in under 5ms) it uses a standard value (50ms).
As long as nobody is gonna try delta-sigma modulation of the main
CPU clock the performance loss is probably neglectible. ;-)
I wrote myself a little testbench and with this patch my system works
stable no matter how often I switch and what applications are running
(mplayer proved to be a good test case) provided that clock frequencies
are not adjusted below the 796 MHz (core) step (K7-2000+).

Patch against linux-2.4.24-0pre2.1mdk from current Mandrake Cooker.
Should apply cleanly to powernow-patched vanilla-2.4.x as well. Probably
relevant for Linux-2.6, too.

-- j



--
Jens David, DG1KJD
Email: dg1kjd@xxxxxxxxxxxxxxxxxxxxx
http://www.afthd.tu-darmstadt.de/~dg1kjd
Work: +49 351 80800 527 --- Home/Mobile: +49 173 6394993




--- linux-2.4.24-0.pre2.1mdk.orig/arch/i386/kernel/powernow-k7.c 2004-01-13 18:02:27.000000000 +0100
+++ linux-2.4.24-0.pre2.1mdk/arch/i386/kernel/powernow-k7.c 2004-01-13 22:26:09.000000000 +0100
@@ -313,8 +313,16 @@ static int powernow_decode_bios (int max
}
dprintk (" voltage regulator)\n");

- latency = psb->settlingtime;
- dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", psb->settlingtime);
+ dprintk (KERN_INFO PFX "Settling Time from BIOS: %d microseconds.\n", psb->settlingtime);
+ if (psb->settlingtime >= 5000) { /* >= 5ms? */
+ dprintk (KERN_INFO PFX "Using BIOS Settling Time.\n");
+ latency = psb->settlingtime;
+ } else {
+ /* no, table probably wrong, be conservative: set to 50 ms */
+ dprintk (KERN_INFO PFX "Settling Time seems too small, correcting!\n");
+ latency = 50000;
+ }
+
dprintk (KERN_INFO PFX "Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);

p += sizeof (struct psb_s);