All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Another powernow-k7 patch for Desktop XP-M usage
@ 2004-10-12  8:18 Hendrik Muhs
  2004-10-14 23:26 ` Nebojsa Trpkovic
  0 siblings, 1 reply; 14+ messages in thread
From: Hendrik Muhs @ 2004-10-12  8:18 UTC (permalink / raw)
  To: cpufreq

[-- Attachment #1: Type: text/plain, Size: 1261 bytes --]

Hi,

I have Athlon XP-M CPU running on Desktop board, which means my BIOS has no 
PST tables. 

After testing the available patches to fix this problem, I combined them an 
wrote my own patch.

The attached patch is for the latest stable kernel 2.6.8.1 and adds the 
following parameters:

- overwrite_table

activates the manually settings, set it to >=1

- multiplier

specifies an array of multipliers, odd multipliers must be multiplied by 10: 
3.5 -> 35

- voltage

specifies an array of VCore voltages in respect to the specified multipliers. 
You have to specify them as mV:
1.125 -> 1125

- switch_latency

sets the state transition latency in microseconds (default 200us)

The patch does not allow overclocking: higher multipliers and/or voltages than 
the maximum specified on CPU will be ignored. 
You do not have to specify voltages, in this case the CPU default will be used 
(on some boards voltage switching is not possible anyway).

example usage:

modprobe powernow-k7 overwrite_table=1 multiplier=3,4,5,6,7,8,9,10

Disclaimer:
It should not be possible to burn the CPU, but some combinations could crash 
the system. I give no guaranty  that it works for your system and/or any 
possibly resulting hardware damage.

Have fun with it,

Hendrik

[-- Attachment #2: powernow-k7.patch --]
[-- Type: text/x-diff, Size: 9211 bytes --]

--- arch/i386/kernel/cpu/cpufreq/powernow-k7.c.orig     2004-08-14 07:36:12.000000000 +0200
+++ arch/i386/kernel/cpu/cpufreq/powernow-k7.c  2004-10-03 18:20:56.000000000 +0200
@@ -76,28 +76,50 @@
 };
 #endif

-/* divide by 1000 to get VID. */
+/* divide by 1000 to get VCore voltage in V. */
 static int mobile_vid_table[32] = {
     2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
     1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
     1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
-    1075, 1050, 1024, 1000, 975, 950, 925, 0,
+    1075, 1050, 1025, 1000, 975, 950, 925, 0,
 };

-/* divide by 10 to get FID. */
+/* divide by 10 to get multiplier. */
 static int fid_codes[32] = {
     110, 115, 120, 125, 50, 55, 60, 65,
     70, 75, 80, 85, 90, 95, 100, 105,
     30, 190, 40, 200, 130, 135, 140, 210,
-    150, 225, 160, 165, 170, 180, -1, -1,
+    150, 220, 160, 165, 170, 180, -1, -1,
 };

+/* translation table for even multiplier to fid */
+static int even_multiplier[20]= {
+    16, 18,  4,  6,  8, 10, 12, 14,    // 3, 4, 5, 6, 7 ,8 , 9, 10
+     0,  2, 20, 22, 24, 26, 28, 29,    // 11, 12, 13, 14, 15, 16, 17, 18
+    17, 19, 23, 25,                    // 19, 20, 21, 22
+};
+
+/* translation table for odd multiplier to fid*/
+static int odd_multiplier[9]={
+    5, 7, 9, 11, 12, 13, 1, 3,        // 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5
+   21,                                       // 13.5
+};
+
+
 /* This parameter is used in order to force ACPI instead of legacy method for
  * configuration purpose.
  */

 static int acpi_force;

+/* This parameters can be used to manually overwrite the tables */
+static int overwrite_table = 0;
+#define MAX_PST 10
+static int maxPSTSize = MAX_PST;
+static int multiplier[MAX_PST]= {[0 ... (MAX_PST - 1)] = 0};
+static int voltage[MAX_PST]= {[0 ... (MAX_PST - 1)] = 0};
+static int switch_latency=0;
+
 static struct cpufreq_frequency_table *powernow_table;

 static unsigned int can_scale_bus;
@@ -414,6 +436,131 @@
 }
 #endif

+static int powernow_manual_settings(union msr_fidvidstatus *fidvidstatus)
+{
+    int i,k, validentry;
+       unsigned int max_multiplier, max_voltage;
+       unsigned int speed, cm;
+       u8 vid, fid;
+       static struct cpufreq_frequency_table *powernow_table_tmp;
+
+       if (switch_latency > 0) {
+               if (switch_latency < 100) {
+                       printk (KERN_INFO PFX "Settling time passed as %d microseconds."
+                               "Should be at least 100. Correcting.\n", switch_latency);
+                       switch_latency = 100;
+               }
+               latency = switch_latency;
+       } else {
+               latency = 200;
+       }
+       dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", latency);
+
+    /* get number of specified multipliers */
+    for (i=0; i< MAX_PST; i++) {
+        if (multiplier[i] == 0) {
+                       number_scales=i;
+                       break;
+               }
+    }
+
+       /* get maximum values */
+       max_multiplier = fid_codes[fidvidstatus->bits.MFID];
+       max_voltage = mobile_vid_table[fidvidstatus->bits.MVID];
+
+       /* allocate memory */
+       powernow_table=kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+       if (!powernow_table)
+               return -ENOMEM;
+       memset(powernow_table,0,(sizeof(struct cpufreq_frequency_table)*(number_scales+1)));
+
+       k=0;
+       for(i=0; i<number_scales; i++)
+       {
+               validentry = 0;
+               if (multiplier[i] != 0) {
+                       /* fix multiplier */
+                       if (multiplier[i] < 30)
+                               multiplier[i]=multiplier[i] * 10;
+
+                       if (multiplier[i] < max_multiplier) {
+                               cm = (multiplier[i]/10);
+                               /* check if odd or even muliplier */
+                               if (multiplier[i]%10) {
+                                       /* odd multiplier */
+                                       if (cm == 16) {
+                                               /* hardcoded because 14.5 and 15.5 fids not possible */
+                                               fid = 27;
+                                               validentry = 1;
+                                       }else if ((cm > 4) && (cm < 14)) {
+                                               fid= odd_multiplier[cm-5];
+                                               validentry = 1;
+                                       }
+                               } else {
+                                       /* even_multiplier */
+                                       if ((cm < 23) && (cm > 2)) {
+                                               fid = even_multiplier[cm-3];
+                                               validentry=1;
+                                       }
+                               }
+                       }
+               }
+
+               if (validentry) {
+                       /* if no voltage specified use CPU default */
+                       if (voltage[i] == 0)
+                               voltage[i] = max_voltage;
+
+                       /* we do not allow higher voltages than the CPU's maximum
+                       925 mV is the minimum */
+                       if ((voltage[i] <= max_voltage) && (voltage[i] >= 925)) {
+                               if (voltage[i] >= 1300) {
+                                       vid = 40 - (voltage[i]/50);
+                               } else {
+                                       vid = 67 - (voltage[i]/25);
+                               }
+                               /* calculate speed */
+                               speed = fsb * fid_codes[fid] / 10;
+                               powernow_table[k].frequency = speed;
+                               powernow_table[k].index=fid; /*lower 8 bits*/
+                               powernow_table[k].index|= (vid << 8); /*upper 8 bits*/
+
+                               if (speed < minimum_speed)
+                                       minimum_speed = speed;
+                               if (speed > maximum_speed)
+                                       maximum_speed = speed;
+
+                               dprintk (KERN_INFO PFX "   FID: 0x%x (%d.%dx [%dMHz])\t", fid, fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000);
+                               dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000, mobile_vid_table[vid]%1000);
+                               k++;
+                       }
+               } else {
+                       // invalid entry
+                       dprintk (KERN_INFO PFX "Entry %d is invalid\n", i+1);
+               }
+       }
+
+       if (k < number_scales) {
+               /* some entrys were invalid need to realloc table */
+               number_scales = k;
+               powernow_table_tmp = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+               if (!powernow_table_tmp) {
+                       kfree(powernow_table);
+                       return -ENOMEM;
+                       }
+               memcpy(powernow_table_tmp,powernow_table,(sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));
+               kfree(powernow_table);
+               powernow_table=powernow_table_tmp;
+       }
+
+
+       /* Terminate frequency list */
+       powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
+       powernow_table[number_scales].index = 0;
+
+       return 0;
+}
+
 static int powernow_decode_bios (int maxfid, int startvid)
 {
        struct psb_s *psb;
@@ -601,6 +748,11 @@
        if (dmi_check_system(powernow_dmi_table) || acpi_force) {
                printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
                result = powernow_acpi_init();
+        }
+        else if (overwrite_table){
+            printk(KERN_INFO PFX "Overwriting PST table with manual settings\n");
+            result = powernow_manual_settings(&fidvidstatus);
+
        } else {
                result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
                if (result) {
@@ -681,6 +833,14 @@

 module_param(acpi_force,  int, 0444);
 MODULE_PARM_DESC(acpi_force, "Force ACPI to be used");
+module_param(overwrite_table,int,0444);
+MODULE_PARM_DESC(overwrite_table, "overwrite table with manually settings");
+module_param_array(multiplier, int, maxPSTSize, 0444);
+MODULE_PARM_DESC(multiplier, "Specifiy up to 10 multipliers, multiply them by 10: 5->50, 5.5->55");
+module_param_array(voltage, int, maxPSTSize, 0444);
+MODULE_PARM_DESC(voltage, "Specify voltages in respect to the given multipliers, specify them in mV: 1.275V -> 1275");
+module_param(switch_latency,  int, 0444);
+MODULE_PARM_DESC(switch_latency, "Set state transition latency in microseconds (default 200us)");

 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
@@ -688,4 +848,3 @@

 late_initcall(powernow_init);
 module_exit(powernow_exit);
-

[-- Attachment #3: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Cpufreq mailing list
Cpufreq@www.linux.org.uk
http://www.linux.org.uk/mailman/listinfo/cpufreq

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-12  8:18 [PATCH] Another powernow-k7 patch for Desktop XP-M usage Hendrik Muhs
@ 2004-10-14 23:26 ` Nebojsa Trpkovic
  2004-10-20  9:43   ` Bruno Ducrot
  0 siblings, 1 reply; 14+ messages in thread
From: Nebojsa Trpkovic @ 2004-10-14 23:26 UTC (permalink / raw)
  To: cpufreq

Hendrik Muhs wrote:

>Hi,
>
>I have Athlon XP-M CPU running on Desktop board, which means my BIOS has no 
>PST tables. 
>
>After testing the available patches to fix this problem, I combined them an 
>wrote my own patch.
>
>The attached patch is for the latest stable kernel 2.6.8.1 and adds the 
>following parameters:
>
>- overwrite_table
>
>activates the manually settings, set it to >=1
>
>- multiplier
>
>specifies an array of multipliers, odd multipliers must be multiplied by 10: 
>3.5 -> 35
>
>- voltage
>
>specifies an array of VCore voltages in respect to the specified multipliers. 
>You have to specify them as mV:
>1.125 -> 1125
>
>- switch_latency
>
>sets the state transition latency in microseconds (default 200us)
>
>The patch does not allow overclocking: higher multipliers and/or voltages than 
>the maximum specified on CPU will be ignored. 
>You do not have to specify voltages, in this case the CPU default will be used 
>(on some boards voltage switching is not possible anyway).
>
>example usage:
>
>modprobe powernow-k7 overwrite_table=1 multiplier=3,4,5,6,7,8,9,10
>
>Disclaimer:
>It should not be possible to burn the CPU, but some combinations could crash 
>the system. I give no guaranty  that it works for your system and/or any 
>possibly resulting hardware damage.
>
>Have fun with it,
>
>Hendrik
>  
>

This is great! It works!

I had to manualy patch my powernow-k7.c but at the end I was able to 
change multiplier on the fly.
Only thing that made problems is switching latency and I had to set it 
to 850 (or more). Anything below 850 would freez system. Is 850 (or 900) 
us a lot?

One thing I just don't know how to do: How to set my max multiplier to 10.5?
I've tried
    modprobe powernow-k7 overwrite_table=1 multiplier=50,105 
switch_latency=850
but it gives 1900MHz (9.5x200MHz), and
    modprobe powernow-k7 overwrite_table=1 multiplier=5,12 
switch_latency=850
or
    modprobe powernow-k7 overwrite_table=1 multiplier=5,13 
switch_latency=850
locks compuers...

Any way to set it to 10.5?


Thank you.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-14 23:26 ` Nebojsa Trpkovic
@ 2004-10-20  9:43   ` Bruno Ducrot
  2004-10-20 22:05     ` Harald Milz
  2004-10-21  0:56     ` Nebojsa Trpkovic
  0 siblings, 2 replies; 14+ messages in thread
From: Bruno Ducrot @ 2004-10-20  9:43 UTC (permalink / raw)
  To: Nebojsa Trpkovic; +Cc: cpufreq

Hi,

On Fri, Oct 15, 2004 at 01:26:43AM +0200, Nebojsa Trpkovic wrote:
> I had to manualy patch my powernow-k7.c but at the end I was able to 
> change multiplier on the fly.
> Only thing that made problems is switching latency and I had to set it 
> to 850 (or more). Anything below 850 would freez system. Is 850 (or 900) 
> us a lot?

It's a very large latency, preventing to actually making any kind
of dynamic frequencies really usefull, and since there is no voltage
scaling, it's IMHO not so usefull for power consuption purpose (though
this may help for cooling purpose).

-- 
Bruno Ducrot

--  Which is worse:  ignorance or apathy?
--  Don't know.  Don't care.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-20  9:43   ` Bruno Ducrot
@ 2004-10-20 22:05     ` Harald Milz
  2004-10-21  0:56     ` Nebojsa Trpkovic
  1 sibling, 0 replies; 14+ messages in thread
From: Harald Milz @ 2004-10-20 22:05 UTC (permalink / raw)
  To: cpufreq

Bruno Ducrot <ducrot@poupinou.org> wrote:

> It's a very large latency, preventing to actually making any kind
> of dynamic frequencies really usefull, and since there is no voltage
> scaling, it's IMHO not so usefull for power consuption purpose (though
> this may help for cooling purpose).

After all, power consumption goes sort of linear with frequency, but square
with voltage. Still, better than nothing. 

-- 
Do not meddle in the affairs of troff, for it is subtle and quick to
anger.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-20  9:43   ` Bruno Ducrot
  2004-10-20 22:05     ` Harald Milz
@ 2004-10-21  0:56     ` Nebojsa Trpkovic
  1 sibling, 0 replies; 14+ messages in thread
From: Nebojsa Trpkovic @ 2004-10-21  0:56 UTC (permalink / raw)
  To: cpufreq

Bruno Ducrot wrote:

>Hi,
>
>On Fri, Oct 15, 2004 at 01:26:43AM +0200, Nebojsa Trpkovic wrote:  
>  
>
>It's a very large latency, preventing to actually making any kind
>of dynamic frequencies really usefull, and since there is no voltage
>scaling, it's IMHO not so usefull for power consuption purpose (though
>this may help for cooling purpose).
>
>  
>

Well, I have only two working states (1GHz and 2.1GHz) that I chage by 
cpudyn. I poll CPU usage once per 500ms because 1GHz Barton is strong 
enough to respond to all my interactive needs without instant switching 
to 2.1GHz. Switching to 2.1GHz is done by some realy huge load 
(compiling gentoo...) and spikes are neutralized.
So, as I calculated, in the worst scenario there can be only 2 frequency 
changes during 1 second, and loosing of ~2ms (~1700ns) per  1 second for 
transition purposes is not so big deal (~0.2% of cpu time).

And, yes, I use it for cooling, but to be cool, too ;)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2005-01-17 15:21   ` Hendrik Muhs
  2005-01-17 16:31     ` Jarkko Lavinen
@ 2005-01-19 15:35     ` Jarkko Lavinen
  1 sibling, 0 replies; 14+ messages in thread
From: Jarkko Lavinen @ 2005-01-19 15:35 UTC (permalink / raw)
  To: cpufreq; +Cc: Hendrik Muhs

[-- Attachment #1: Type: text/plain, Size: 1815 bytes --]

On Mon, Jan 17, 2005 at 04:21:52PM +0100, Hendrik Muhs wrote:
> Why not let the user specify the FSB? I mean if this is the issue, why do you 
> take the multiplier? I would add a module option "fsb" instead.

Attached is a patch for 2.6.10 with user specified fsb, as suggested above.
It is based on Hendrik's earlier patch.

It seems cpu clock value is so coarsely known that the FSB cannot be
accurately calculated from it even if the multiplier can be calculated.  
It is indeed better to just let user to specify fixed fsb value. 

I load the module with parameters:

  powernow-k7 overwrite_table=1 fsb=133333 multiplier=3,4,5,6,7,8,9

The fsb frequency can be given either in khz or mhz. khz will give more
digits and rounded cpu frequencies will look prettier. 

Using cpufreq.debug=2 on kernel command line. Dmesg says:

  powernow: PowerNOW! Technology present. Can scale: frequency and voltage.
  powernow-k7: MSR reported multiplier 14.0
  powernow-k7: Current multiplier 9.0. CPU running at 1222MHz
  powernow-k7: FSB: 133.333 MHz
  powernow: Overwriting PST table with manual settings
  powernow-k7: Settling Time: 200 microseconds.
  powernow-k7:    FID: 0x10 (3.0x [400MHz])       VID: 0xb (1.450V)
  powernow-k7:    FID: 0x12 (4.0x [533MHz])       VID: 0xb (1.450V)
  powernow-k7:    FID: 0x4 (5.0x [667MHz])        VID: 0xb (1.450V)
  powernow-k7:    FID: 0x6 (6.0x [800MHz])        VID: 0xb (1.450V)
  powernow-k7:    FID: 0x8 (7.0x [933MHz])        VID: 0xb (1.450V)
  powernow-k7:    FID: 0xa (8.0x [1067MHz])       VID: 0xb (1.450V)
  powernow-k7:    FID: 0xc (9.0x [1200MHz])       VID: 0xb (1.450V)
  powernow: Minimum speed 400 MHz. Maximum speed 1200 MHz.


Frequency scaling works well and my system is stable. Voltage scaling 
is not available and I keep Vcore at 1.15V.

Jarkko Lavinen

[-- Attachment #2: powernow-k7.c-2610.diff --]
[-- Type: text/plain, Size: 9020 bytes --]

--- linux-2.6.10/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2004-12-24 23:33:49.000000000 +0200
+++ linux-2.6.10-new/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2005-01-19 17:01:23.000000000 +0200
@@ -72,7 +72,7 @@
     2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
     1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
     1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
-    1075, 1050, 1024, 1000, 975, 950, 925, 0,
+    1075, 1050, 1025, 1000, 975, 950, 925, 0,
 };
 #endif
 
@@ -81,15 +81,39 @@
     110, 115, 120, 125, 50, 55, 60, 65,
     70, 75, 80, 85, 90, 95, 100, 105,
     30, 190, 40, 200, 130, 135, 140, 210,
-    150, 225, 160, 165, 170, 180, -1, -1,
+    150, 220, 160, 165, 170, 180, -1, -1,
 };
 
+/* translation table for even multiplier to fid */
+static int even_multiplier[20] = {
+    16, 18, 4, 6, 8, 10, 12, 14,	// 3, 4, 5, 6, 7 ,8 , 9, 10
+    0, 2, 20, 22, 24, 26, 28, 29,	// 11, 12, 13, 14, 15, 16, 17, 18
+    17, 19, 23, 25,		        // 19, 20, 21, 22
+};
+
+/* translation table for odd multiplier to fid*/
+static int odd_multiplier[9] = {
+    5, 7, 9, 11, 13, 15, 1, 3,	// 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5
+    21,				// 13.5
+};
+
+
 /* This parameter is used in order to force ACPI instead of legacy method for
  * configuration purpose.
  */
 
 static int acpi_force;
 
+/* This parameters can be used to manually overwrite the tables */
+static int overwrite_table = 0;
+#define MAX_PST 10
+static int multiplier_arr_size = MAX_PST;
+static int voltage_arr_size = MAX_PST;
+static int multiplier[MAX_PST] = {[0 ... (MAX_PST - 1)] = 0 };
+static int voltage[MAX_PST] = {[0 ... (MAX_PST - 1)] = 0 };
+static int switch_latency = 0;
+static unsigned int fsb = 0;
+
 static struct cpufreq_frequency_table *powernow_table;
 
 static unsigned int can_scale_bus;
@@ -97,7 +121,6 @@
 static unsigned int minimum_speed=-1;
 static unsigned int maximum_speed;
 static unsigned int number_scales;
-static unsigned int fsb;
 static unsigned int latency;
 static char have_a0;
 
@@ -200,7 +223,7 @@
 
 		dprintk ("   FID: 0x%x (%d.%dx [%dMHz])  "
 			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, 
-			 fid_codes[fid] % 10, speed/1000, vid,	
+			 fid_codes[fid] % 10, (speed + 500)/1000, vid,	
 			 mobile_vid_table[vid]/1000,
 			 mobile_vid_table[vid]%1000);
 	}
@@ -374,7 +397,7 @@
 
 		dprintk ("   FID: 0x%x (%d.%dx [%dMHz])  "
 			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, 
-			 fid_codes[fid] % 10, speed/1000, vid,	
+			 fid_codes[fid] % 10, (speed + 500)/1000, vid,	
 			 mobile_vid_table[vid]/1000,
 			 mobile_vid_table[vid]%1000);
 
@@ -413,6 +436,131 @@
 }
 #endif
 
+static int powernow_manual_settings(union msr_fidvidstatus *fidvidstatus)
+{
+	int i,k, validentry;
+	unsigned int max_multiplier, max_voltage;
+	unsigned int speed, cm;
+	u8 vid, fid;
+	static struct cpufreq_frequency_table *powernow_table_tmp;
+	
+	if (switch_latency > 0) {
+		if (switch_latency < 100) {
+			printk (KERN_INFO PFX "Settling time passed as %d microseconds."
+				"Should be at least 100. Correcting.\n", switch_latency);
+			switch_latency = 100;
+		}
+		latency = switch_latency;
+	} else {
+		latency = 200;
+	}
+	dprintk ("Settling Time: %d microseconds.\n", latency);
+
+	/* get number of specified multipliers */
+	number_scales = multiplier_arr_size;
+	for (i=0; i < multiplier_arr_size; i++) {
+		if (multiplier[i] == 0) {
+			number_scales=i;
+			break;
+		}
+	}
+
+	/* get maximum values */
+	max_multiplier = fid_codes[fidvidstatus->bits.MFID];
+	max_voltage = mobile_vid_table[fidvidstatus->bits.MVID];
+
+	/* allocate memory */
+	powernow_table=kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+	if (!powernow_table)
+		return -ENOMEM;
+	memset(powernow_table,0,(sizeof(struct cpufreq_frequency_table)*(number_scales+1)));
+
+	k=0;
+	for(i=0; i<number_scales; i++) {
+		validentry = 0;
+		if (multiplier[i] != 0) {
+			/* fix multiplier */
+			if (multiplier[i] < 30)
+				multiplier[i]=multiplier[i] * 10;
+
+			if (multiplier[i] < max_multiplier) {
+				cm = (multiplier[i]/10);
+
+				/* check if odd or even muliplier */
+				if (multiplier[i]%10) {
+					/* odd multiplier */
+					if (cm == 16) {
+						/* hardcoded because 14.5 and 15.5 fids not possible */
+						fid = 27;
+						validentry = 1;
+					} else if ((cm > 4) && (cm < 14)) {
+						fid= odd_multiplier[cm-5];
+						validentry = 1;
+					}
+				} else {
+					/* even_multiplier */
+					if ((cm < 23) && (cm > 2)) {
+						fid = even_multiplier[cm-3];
+						validentry=1;
+					}
+				}
+			}
+		}
+
+		if (validentry) {
+			/* if no voltage specified use CPU default */
+			if (voltage[i] == 0)
+				voltage[i] = max_voltage;
+
+			/* we do not allow higher voltages than the CPU's maximum
+			   925 mV is the minimum */
+			if ((voltage[i] <= max_voltage) && (voltage[i] >= 925)) {
+				if (voltage[i] >= 1300) {
+					vid = 40 - (voltage[i]/50);
+				} else {
+					vid = 67 - (voltage[i]/25);
+				}
+				/* calculate speed */
+				speed = fsb * fid_codes[fid] / 10;
+				powernow_table[k].frequency = speed;
+				powernow_table[k].index=fid; /*lower 8 bits*/
+				powernow_table[k].index|= (vid << 8); /*upper 8 bits*/
+
+				if (speed < minimum_speed)
+					minimum_speed = speed;
+				if (speed > maximum_speed)
+					maximum_speed = speed;
+
+				dprintk ("   FID: 0x%x (%d.%dx [%dMHz])\t", fid, fid_codes[fid] / 10, fid_codes[fid] % 10, (speed + 500)/1000);
+				printk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000, mobile_vid_table[vid]%1000);
+				k++;
+			}
+		} else {
+			// invalid entry
+			dprintk ("Entry %d is invalid\n", i+1);
+		}
+	}
+
+	if (k < number_scales) {
+		/* some entrys were invalid need to realloc table */
+		number_scales = k;
+		powernow_table_tmp = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+		if (!powernow_table_tmp) {
+			kfree(powernow_table);
+			return -ENOMEM;
+		}
+		memcpy(powernow_table_tmp,powernow_table,(sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));
+		kfree(powernow_table);
+		powernow_table=powernow_table_tmp;
+	}
+
+	/* Terminate frequency list */
+	powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
+	powernow_table[number_scales].index = 0;
+       
+	return 0;
+}
+
 static int powernow_decode_bios (int maxfid, int startvid)
 {
 	struct psb_s *psb;
@@ -586,8 +734,28 @@
 
 	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
+	if (fsb) {
+		unsigned int mult;
+
+		if (fsb < 1000)
+			fsb *= 1000;
+
+		if (fsb < 1000 || fsb > 1000000) {
+			printk(KERN_WARNING PFX "FSB %ukhz out of range\n", fsb);
+			return -EINVAL;
+		}
+
+		mult = ((2*cpu_khz + fsb/2) / fsb) * 5;
+		if (mult != fid_codes[fidvidstatus.bits.MFID])
+			dprintk("MSR reported multiplier %u.%u\n", fid_codes[fidvidstatus.bits.MFID]/10, fid_codes[fidvidstatus.bits.MFID]%10);
+
+		dprintk("Current multiplier %u.%u. CPU running at %luMHz\n", mult/10, mult%10, (cpu_khz + 500)/1000);
+		if (mult < 30 || mult >= 230)
+			dprintk("Multiplier %u.%u not possible\n", mult/10, mult%10);
+	} else
 	/* A K7 with powernow technology is set to max frequency by BIOS */
 	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];
+
 	if (!fsb) {
 		printk(KERN_WARNING PFX "can not determine bus frequency\n");
 		return -EINVAL;
@@ -597,6 +765,9 @@
 	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
 		printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
 		result = powernow_acpi_init();
+        } else if (overwrite_table){
+		printk(KERN_INFO PFX "Overwriting PST table with manual settings\n");
+		result = powernow_manual_settings(&fidvidstatus);
 	} else {
 		result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
 		if (result) {
@@ -620,7 +791,7 @@
 		return result;
 
 	printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
-				minimum_speed/1000, maximum_speed/1000);
+				(minimum_speed + 500)/1000, (maximum_speed + 500)/1000);
 
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 
@@ -678,6 +849,17 @@
 module_param(acpi_force,  int, 0444);
 MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
 
+module_param(overwrite_table,int,0444);
+MODULE_PARM_DESC(overwrite_table, "overwrite table with manually settings");
+module_param(fsb, uint, 0444);
+MODULE_PARM_DESC(fsb, "(MHz) overrides the calculated FSB");
+module_param_array(multiplier, int, &multiplier_arr_size, 0444);
+MODULE_PARM_DESC(multiplier, "Specifiy up to 10 multipliers, multiply them by 10: 5->50, 5.5->55");
+module_param_array(voltage, int, &voltage_arr_size, 0444);
+MODULE_PARM_DESC(voltage, "Specify voltages in respect to the given multipliers, specify them in mV: 1.275V -> 1275");
+module_param(switch_latency,  int, 0444);
+MODULE_PARM_DESC(switch_latency, "Set state transition latency in microseconds (default 200us)");
+
 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
 MODULE_LICENSE ("GPL");

[-- Attachment #3: Type: text/plain, Size: 147 bytes --]

_______________________________________________
Cpufreq mailing list
Cpufreq@lists.linux.org.uk
http://lists.linux.org.uk/mailman/listinfo/cpufreq

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2005-01-17 15:21   ` Hendrik Muhs
@ 2005-01-17 16:31     ` Jarkko Lavinen
  2005-01-19 15:35     ` Jarkko Lavinen
  1 sibling, 0 replies; 14+ messages in thread
From: Jarkko Lavinen @ 2005-01-17 16:31 UTC (permalink / raw)
  To: Hendrik Muhs; +Cc: cpufreq, Jarkko Lavinen

[-- Attachment #1: Type: text/plain, Size: 948 bytes --]

On Mon, Jan 17, 2005 at 04:21:52PM +0100, Hendrik Muhs wrote:
> Which motherboard do you have?

My motherboard is Abit KD7A. I am using FSB 133 and multiplier 9 at BIOS and
the CPU is running at 1200MHz when kernel boots.

In powernow_cpu_init() the multiploer is asked by:

  rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);

  /* A K7 with powernow technology is set to max frequency by BIOS */
  fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];

14 is then used here as divisor and FSB 87.050MHz is used.

Either overriding FSB or overriding the multiplier would avoid wrong 
FSB being used.  I think your suggestion to specify FSB would be
more user friedly and intuitive.  One could then calculate the
real multiplier and the precise FSB.

> Anyway, I miss your patch. You have forgotten to attach it!

Attached. I didn't intend to send it to the list at all since it
is 96% the same as the patch you sent previously.

Cheers
Jarkko

[-- Attachment #2: powernow-k7.c.diff --]
[-- Type: text/plain, Size: 7734 bytes --]

--- powernow-k7.c.orig	2005-01-14 12:14:02.000000000 +0200
+++ powernow-k7.c	2005-01-14 13:31:21.000000000 +0200
@@ -71,7 +71,7 @@
     2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
     1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
     1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
-    1075, 1050, 1024, 1000, 975, 950, 925, 0,
+    1075, 1050, 1025, 1000, 975, 950, 925, 0,
 };
 
 /* divide by 10 to get FID. */
@@ -79,9 +79,23 @@
     110, 115, 120, 125, 50, 55, 60, 65,
     70, 75, 80, 85, 90, 95, 100, 105,
     30, 190, 40, 200, 130, 135, 140, 210,
-    150, 225, 160, 165, 170, 180, -1, -1,
+    150, 220, 160, 165, 170, 180, -1, -1,
 };
 
+/* translation table for even multiplier to fid */
+static int even_multiplier[20] = {
+    16, 18, 4, 6, 8, 10, 12, 14,	// 3, 4, 5, 6, 7 ,8 , 9, 10
+    0, 2, 20, 22, 24, 26, 28, 29,	// 11, 12, 13, 14, 15, 16, 17, 18
+    17, 19, 23, 25,		        // 19, 20, 21, 22
+};
+
+/* translation table for odd multiplier to fid*/
+static int odd_multiplier[9] = {
+    5, 7, 9, 11, 13, 15, 1, 3,	// 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5
+    21,				// 13.5
+};
+
+
 /* This parameter is used in order to force ACPI instead of legacy method for
  * configuration purpose.
  */
@@ -89,6 +103,15 @@
 static int acpi_force;
 static int debug;
 
+/* This parameters can be used to manually overwrite the tables */
+static int overwrite_table = 0;
+static int multiplier_limit = 0;
+#define MAX_PST 10
+static int maxPSTSize = MAX_PST;
+static int multiplier[MAX_PST] = {[0 ... (MAX_PST - 1)] = 0 };
+static int voltage[MAX_PST] = {[0 ... (MAX_PST - 1)] = 0 };
+static int switch_latency = 0;
+
 static struct cpufreq_frequency_table *powernow_table;
 
 static unsigned int can_scale_bus;
@@ -420,6 +443,131 @@
 }
 #endif
 
+static int powernow_manual_settings(union msr_fidvidstatus *fidvidstatus)
+{
+	int i,k, validentry;
+	unsigned int max_multiplier, max_voltage;
+	unsigned int speed, cm;
+	u8 vid, fid;
+	static struct cpufreq_frequency_table *powernow_table_tmp;
+	
+	if (switch_latency > 0) {
+		if (switch_latency < 100) {
+			printk (KERN_INFO PFX "Settling time passed as %d microseconds."
+				"Should be at least 100. Correcting.\n", switch_latency);
+			switch_latency = 100;
+		}
+		latency = switch_latency;
+	} else {
+		latency = 200;
+	}
+	dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", latency);
+
+	/* get number of specified multipliers */
+	for (i=0; i< MAX_PST; i++) {
+		if (multiplier[i] == 0) {
+			number_scales=i;
+			break;
+		}
+	}
+
+	/* get maximum values */
+	max_multiplier = fid_codes[fidvidstatus->bits.MFID];
+	max_voltage = mobile_vid_table[fidvidstatus->bits.MVID];
+
+	/* allocate memory */
+	powernow_table=kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+	if (!powernow_table)
+		return -ENOMEM;
+	memset(powernow_table,0,(sizeof(struct cpufreq_frequency_table)*(number_scales+1)));
+
+	k=0;
+	for(i=0; i<number_scales; i++)
+	{
+		validentry = 0;
+		if (multiplier[i] != 0) {
+			/* fix multiplier */
+			if (multiplier[i] < 30)
+				multiplier[i]=multiplier[i] * 10;
+
+			if (multiplier[i] < max_multiplier) {
+				cm = (multiplier[i]/10);
+				/* check if odd or even muliplier */
+				if (multiplier[i]%10) {
+					/* odd multiplier */
+					if (cm == 16) {
+						/* hardcoded because 14.5 and 15.5 fids not possible */
+						fid = 27;
+						validentry = 1;
+					}else if ((cm > 4) && (cm < 14)) {
+						fid= odd_multiplier[cm-5];
+						validentry = 1;
+					}
+				} else {
+					/* even_multiplier */
+					if ((cm < 23) && (cm > 2)) {
+						fid = even_multiplier[cm-3];
+						validentry=1;
+					}
+				}
+			}
+		}
+
+		if (validentry) {
+			/* if no voltage specified use CPU default */
+			if (voltage[i] == 0)
+				voltage[i] = max_voltage;
+
+			/* we do not allow higher voltages than the CPU's maximum
+			   925 mV is the minimum */
+			if ((voltage[i] <= max_voltage) && (voltage[i] >= 925)) {
+				if (voltage[i] >= 1300) {
+					vid = 40 - (voltage[i]/50);
+				} else {
+					vid = 67 - (voltage[i]/25);
+				}
+				/* calculate speed */
+				speed = fsb * fid_codes[fid] / 10;
+				powernow_table[k].frequency = speed;
+				powernow_table[k].index=fid; /*lower 8 bits*/
+				powernow_table[k].index|= (vid << 8); /*upper 8 bits*/
+
+				if (speed < minimum_speed)
+					minimum_speed = speed;
+				if (speed > maximum_speed)
+					maximum_speed = speed;
+
+				dprintk (KERN_INFO PFX "   FID: 0x%x (%d.%dx [%dMHz])\t", fid, fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000);
+				dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000, mobile_vid_table[vid]%1000);
+				k++;
+			}
+		} else {
+			// invalid entry
+			dprintk (KERN_INFO PFX "Entry %d is invalid\n", i+1);
+		}
+	}
+
+	if (k < number_scales) {
+		/* some entrys were invalid need to realloc table */
+		number_scales = k;
+		powernow_table_tmp = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+		if (!powernow_table_tmp) {
+			kfree(powernow_table);
+			return -ENOMEM;
+		}
+		memcpy(powernow_table_tmp,powernow_table,(sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));
+		kfree(powernow_table);
+		powernow_table=powernow_table_tmp;
+	}
+       
+
+	/* Terminate frequency list */
+	powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
+	powernow_table[number_scales].index = 0;
+       
+	return 0;
+}
+
 static int powernow_decode_bios (int maxfid, int startvid)
 {
 	struct psb_s *psb;
@@ -589,7 +737,7 @@
 static int __init powernow_cpu_init (struct cpufreq_policy *policy)
 {
 	union msr_fidvidstatus fidvidstatus;
-	int result;
+	int result, max_div;
 
 	if (policy->cpu != 0)
 		return -ENODEV;
@@ -597,7 +745,16 @@
 	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
 	/* A K7 with powernow technology is set to max frequency by BIOS */
-	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];
+	max_div = fid_codes[fidvidstatus.bits.MFID];
+	if (multiplier_limit) {
+		if (multiplier_limit < 30)
+			multiplier_limit *= 10;  // Even multiplier
+		
+		if (multiplier_limit < max_div)
+			max_div = multiplier_limit;
+	}
+
+	fsb = (10 * cpu_khz) / max_div;
 	if (!fsb) {
 		printk(KERN_WARNING PFX "can not determine bus frequency\n");
 		return -EINVAL;
@@ -607,6 +764,9 @@
 	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
 		printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
 		result = powernow_acpi_init();
+        } else if (overwrite_table){
+		printk(KERN_INFO PFX "Overwriting PST table with manual settings\n");
+		result = powernow_manual_settings(&fidvidstatus);
 	} else {
 		result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
 		if (result) {
@@ -690,6 +850,17 @@
 module_param(acpi_force,  int, 0444);
 MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
 
+module_param(overwrite_table,int,0444);
+MODULE_PARM_DESC(overwrite_table, "overwrite table with manually settings");
+module_param(multiplier_limit, int, 0444);
+MODULE_PARM_DESC(overwrite_table, "The highest allowed multiplier even x1, odd x10");
+module_param_array(multiplier, int, maxPSTSize, 0444);
+MODULE_PARM_DESC(multiplier, "Specifiy up to 10 multipliers, multiply them by 10: 5->50, 5.5->55");
+module_param_array(voltage, int, maxPSTSize, 0444);
+MODULE_PARM_DESC(voltage, "Specify voltages in respect to the given multipliers, specify them in mV: 1.275V -> 1275");
+module_param(switch_latency,  int, 0444);
+MODULE_PARM_DESC(switch_latency, "Set state transition latency in microseconds (default 200us)");
+
 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
 MODULE_LICENSE ("GPL");

[-- Attachment #3: Type: text/plain, Size: 145 bytes --]

_______________________________________________
Cpufreq mailing list
Cpufreq@lists.linux.org.uk
http://www.linux.org.uk/mailman/listinfo/cpufreq

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2005-01-14 11:46 ` Jarkko Lavinen
@ 2005-01-17 15:21   ` Hendrik Muhs
  2005-01-17 16:31     ` Jarkko Lavinen
  2005-01-19 15:35     ` Jarkko Lavinen
  0 siblings, 2 replies; 14+ messages in thread
From: Hendrik Muhs @ 2005-01-17 15:21 UTC (permalink / raw)
  To: cpufreq; +Cc: Jarkko Lavinen

Hi,

> On Fri Oct 15, 2004 at 08:05:07, Hendrik Muhs wrote:
> > A new corrected patch is attached to this mail
>
> Many thanks for the XP-M patch.  I am using it on 2.6.9 and running
> XP-M at 1.1Vcore. The max cpu clock at this Vcore is about 1200MHz
> or multiplier 9 on 133MHz FSB.
>
> The patch assumes the CPU is running at the highest normal multiplier,
> that would be 14 cpu running at around 1800MHz. It then calculates
> the FSB frquency from cpu clock and the assumed multiplier.  As a result,
> a wrong FSB and frequencies are calculated.

Strange. If I understand it correctly, your BIOS lets you set the start 
multiplier but does not report it correctly.

(In my BIOS I can also set a start multiplier, but that does not work at all. 
The CPU is always started with the highest multiplier (supplied by the CPU))

Which motherboard do you have?

>
> For a quick remedy, I added a new module option "multiplier_limit" which
> limits the queried multiplier to no higher than the given limit.
>

Why not let the user specify the FSB? I mean if this is the issue, why do you 
take the multiplier? I would add a module option "fsb" instead.

BTW. Wasn't there another report recently about broken FSB detection on the 
list?

The mailinglist archives are broken, so I can not check it. The links in the 
pages are still refering to www.linux.org.uk instead of lists.linux.org.uk.

>   overwrite_table=1 multiplier=3,4,5,6,7,8,9 debug=1 multiplier_limit=9
>
>   powernow: PowerNOW! Technology present. Can scale: frequency and voltage.
>   powernow: FSB: 135.405 MHz
>   powernow: Overwriting PST table with manual settings
>   powernow: Settling Time: 200 microseconds.
>   powernow:    FID: 0x10 (3.0x [406MHz])  VID: 0xb (1.450V)
>   powernow:    FID: 0x12 (4.0x [541MHz])  VID: 0xb (1.450V)
>   powernow:    FID: 0x4 (5.0x [677MHz])   VID: 0xb (1.450V)
>   powernow:    FID: 0x6 (6.0x [812MHz])   VID: 0xb (1.450V)
>   powernow:    FID: 0x8 (7.0x [947MHz])   VID: 0xb (1.450V)
>   powernow:    FID: 0xa (8.0x [1083MHz])  VID: 0xb (1.450V)
>   powernow:    FID: 0xc (9.0x [1218MHz])  VID: 0xb (1.450V)
>   powernow: Minimum speed 406 MHz. Maximum speed 1218 MHz.
>
> With this modification the FSB and CPU frequencies are repoted correctly.
> It would be better if the currently used multiplier could be detected
> without resorting to setting manual limit, though.

Yes, but as I said, I assume that your BIOS does not report it correctly. So I 
do not see a way to do this.

Anyway, I miss your patch. You have forgotten to attach it!

Regards,

Hendrik

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-15  7:05 Hendrik Muhs
  2004-10-15 22:28 ` Nebojsa Trpkovic
  2004-10-16 16:11 ` mark newman
@ 2005-01-14 11:46 ` Jarkko Lavinen
  2005-01-17 15:21   ` Hendrik Muhs
  2 siblings, 1 reply; 14+ messages in thread
From: Jarkko Lavinen @ 2005-01-14 11:46 UTC (permalink / raw)
  To: cpufreq; +Cc: Hendrik Muhs

On Fri Oct 15, 2004 at 08:05:07, Hendrik Muhs wrote:
> A new corrected patch is attached to this mail

Many thanks for the XP-M patch.  I am using it on 2.6.9 and running
XP-M at 1.1Vcore. The max cpu clock at this Vcore is about 1200MHz
or multiplier 9 on 133MHz FSB. 

The patch assumes the CPU is running at the highest normal multiplier, 
that would be 14 cpu running at around 1800MHz. It then calculates
the FSB frquency from cpu clock and the assumed multiplier.  As a result, 
a wrong FSB and frequencies are calculated.

For a quick remedy, I added a new module option "multiplier_limit" which
limits the queried multiplier to no higher than the given limit.

  overwrite_table=1 multiplier=3,4,5,6,7,8,9 debug=1 multiplier_limit=9

  powernow: PowerNOW! Technology present. Can scale: frequency and voltage.
  powernow: FSB: 135.405 MHz
  powernow: Overwriting PST table with manual settings
  powernow: Settling Time: 200 microseconds.
  powernow:    FID: 0x10 (3.0x [406MHz])  VID: 0xb (1.450V)
  powernow:    FID: 0x12 (4.0x [541MHz])  VID: 0xb (1.450V)
  powernow:    FID: 0x4 (5.0x [677MHz])   VID: 0xb (1.450V)
  powernow:    FID: 0x6 (6.0x [812MHz])   VID: 0xb (1.450V)
  powernow:    FID: 0x8 (7.0x [947MHz])   VID: 0xb (1.450V)
  powernow:    FID: 0xa (8.0x [1083MHz])  VID: 0xb (1.450V)
  powernow:    FID: 0xc (9.0x [1218MHz])  VID: 0xb (1.450V)
  powernow: Minimum speed 406 MHz. Maximum speed 1218 MHz.

With this modification the FSB and CPU frequencies are repoted correctly.
It would be better if the currently used multiplier could be detected 
without resorting to setting manual limit, though.

Jarkko Lavinen

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
@ 2004-12-01 20:09 Hendrik Muhs
  0 siblings, 0 replies; 14+ messages in thread
From: Hendrik Muhs @ 2004-12-01 20:09 UTC (permalink / raw)
  To: cpufreq

Hi,


> 
> Still can't set multiplier 11. I'm able to run CPU on 10.5x200, but not 
> at 11x200. If I use
> 
> powernow-k7 overwrite_table=1 multiplier=50,60,70,80,90,110
> 
> or
> 
> powernow-k7 overwrite_table=1 multiplier=50,60,70,80,90,11
> 
> maximum frequency becomes 1800MHz (9x200) and it's second to last 
> multiplier...

Strange, works for me:

modprobe powernow-k7 overwrite_table=1 multiplier=50,60,70,80,90,110

dmesg:

powernow: PowerNOW! Technology present. Can scale: frequency and voltage.
powernow: FSB: 100.074 MHz
powernow: Overwriting PST table with manual settings
powernow: Settling Time: 200 microseconds.
powernow:    FID: 0x4 (5.0x [500MHz])   VID: 0xb (1.450V)
powernow:    FID: 0x6 (6.0x [600MHz])   VID: 0xb (1.450V)
powernow:    FID: 0x8 (7.0x [700MHz])   VID: 0xb (1.450V)
powernow:    FID: 0xa (8.0x [800MHz])   VID: 0xb (1.450V)
powernow:    FID: 0xc (9.0x [900MHz])   VID: 0xb (1.450V)
powernow:    FID: 0x0 (11.0x [1100MHz]) VID: 0xb (1.450V)
powernow: Minimum speed 500 MHz. Maximum speed 1100 MHz.

cat /proc/cpuinfo:

processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 6
model           : 10
model name      : mobile AMD Athlon(tm) MP-M 1700+
stepping        : 0
cpu MHz         : 1100.815
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca 
cmov pat pse36 mmx fxsr sse syscall mp mmxext 3dnowext 3dnow
bogomips        : 2176.03


Could you please post your dmesg output and the output from 
'cat /proc/cpuinfo' after modprobe 'ing the module?

Hendrik
 
> 
> 
> 
> 
> Nebojsa Trpkovic wrote:
> 
> > Hendrik Muhs wrote:
> >
> >> You found a bug! There is an error in the translation table:
> >>
> >> +/* translation table for odd multiplier to fid*/
> >> +static int odd_multiplier[9]={
> >> +    5, 7, 9, 11, 12, 13, 1, 3,        +   
> >> 21,                                      +};
> >>
> >> should be (13 instead of 12, 15 instead of 13):
> >>
> >> +/* translation table for odd multiplier to fid*/
> >> +static int odd_multiplier[9]={
> >> +    5, 7, 9, 11, 13, 15, 1, 3,       +   
> >> 21,                                      +};
> >>
> >> A new corrected patch is attached to this mail
> >>
> >> Hendrik
> >>  
> >>
> >>
> > That works!
> >
> > Finaly I have my Barton 2500+ fully modded :D
> >
> > First, I've set it's FSB from 166MHz to 200MHz (L12 mod)
> > and then it became Mobile (L5 mod)
> >
> > Now it runs at 1GHz and switchs to 2.1GHz if needed instead of boring 
> > 1833MHz :D
> >
> >
> > Great work!
> > Thank you all!
> >

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-15 22:28 ` Nebojsa Trpkovic
@ 2004-11-29 21:36   ` Nebojsa Trpkovic
  0 siblings, 0 replies; 14+ messages in thread
From: Nebojsa Trpkovic @ 2004-11-29 21:36 UTC (permalink / raw)
  To: cpufreq

Still can't set multiplier 11. I'm able to run CPU on 10.5x200, but not 
at 11x200. If I use

powernow-k7 overwrite_table=1 multiplier=50,60,70,80,90,110

or

powernow-k7 overwrite_table=1 multiplier=50,60,70,80,90,11

maximum frequency becomes 1800MHz (9x200) and it's second to last 
multiplier...




Nebojsa Trpkovic wrote:

> Hendrik Muhs wrote:
>
>> You found a bug! There is an error in the translation table:
>>
>> +/* translation table for odd multiplier to fid*/
>> +static int odd_multiplier[9]={
>> +    5, 7, 9, 11, 12, 13, 1, 3,        +   
>> 21,                                      +};
>>
>> should be (13 instead of 12, 15 instead of 13):
>>
>> +/* translation table for odd multiplier to fid*/
>> +static int odd_multiplier[9]={
>> +    5, 7, 9, 11, 13, 15, 1, 3,       +   
>> 21,                                      +};
>>
>> A new corrected patch is attached to this mail
>>
>> Hendrik
>>  
>>
>>
> That works!
>
> Finaly I have my Barton 2500+ fully modded :D
>
> First, I've set it's FSB from 166MHz to 200MHz (L12 mod)
> and then it became Mobile (L5 mod)
>
> Now it runs at 1GHz and switchs to 2.1GHz if needed instead of boring 
> 1833MHz :D
>
>
> Great work!
> Thank you all!
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-15  7:05 Hendrik Muhs
  2004-10-15 22:28 ` Nebojsa Trpkovic
@ 2004-10-16 16:11 ` mark newman
  2005-01-14 11:46 ` Jarkko Lavinen
  2 siblings, 0 replies; 14+ messages in thread
From: mark newman @ 2004-10-16 16:11 UTC (permalink / raw)
  To: cpufreq


> 
> A new corrected patch is attached to this mail
> 
> Hendrik

Hendrick.

Thanks for this patch.  I can now scale my xpm up to
full speed as needed.  I was stuck at 800 mhz which
was fine most of the time on my media box but a pain
when I was compiling its gentoo OS.  This helps me a
lot

I had to manually apply some of the patch but it works
fine.


Thanks

Mark


	
	
		
___________________________________________________________ALL-NEW Yahoo! Messenger - all new features - even more fun!  http://uk.messenger.yahoo.com

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Another powernow-k7 patch for Desktop XP-M usage
  2004-10-15  7:05 Hendrik Muhs
@ 2004-10-15 22:28 ` Nebojsa Trpkovic
  2004-11-29 21:36   ` Nebojsa Trpkovic
  2004-10-16 16:11 ` mark newman
  2005-01-14 11:46 ` Jarkko Lavinen
  2 siblings, 1 reply; 14+ messages in thread
From: Nebojsa Trpkovic @ 2004-10-15 22:28 UTC (permalink / raw)
  To: cpufreq

Hendrik Muhs wrote:

>You found a bug! There is an error in the translation table:
>
>+/* translation table for odd multiplier to fid*/
>+static int odd_multiplier[9]={
>+    5, 7, 9, 11, 12, 13, 1, 3,        
>+   21,                                      
>+};
>
>should be (13 instead of 12, 15 instead of 13):
>
>+/* translation table for odd multiplier to fid*/
>+static int odd_multiplier[9]={
>+    5, 7, 9, 11, 13, 15, 1, 3,       
>+   21,                                      
>+};
>
>A new corrected patch is attached to this mail
>
>Hendrik
>  
>
>
That works!

Finaly I have my Barton 2500+ fully modded :D

First, I've set it's FSB from 166MHz to 200MHz (L12 mod)
and then it became Mobile (L5 mod)

Now it runs at 1GHz and switchs to 2.1GHz if needed instead of boring 
1833MHz :D


Great work!
Thank you all!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH] Another powernow-k7 patch for Desktop XP-M usage
@ 2004-10-15  7:05 Hendrik Muhs
  2004-10-15 22:28 ` Nebojsa Trpkovic
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Hendrik Muhs @ 2004-10-15  7:05 UTC (permalink / raw)
  To: cpufreq

[-- Attachment #1: Type: text/plain, Size: 1275 bytes --]

> This is great! It works!
> 
> I had to manualy patch my powernow-k7.c but at the end I was able to 
> change multiplier on the fly.
> Only thing that made problems is switching latency and I had to set it 
> to 850 (or more). Anything below 850 would freez system. Is 850 (or 900) 
> us a lot?

My systems works with the default of 200 (have not tried less then 200). 

I think it is very hardware dependent and its not possible to write a driver 
that works for all systems. You have to try to find the values that works for 
your system.

> 
> One thing I just don't know how to do: How to set my max multiplier to 10.5?
> I've tried
>     modprobe powernow-k7 overwrite_table=1 multiplier=50,105 
> switch_latency=850
> but it gives 1900MHz (9.5x200MHz), 

You found a bug! There is an error in the translation table:

+/* translation table for odd multiplier to fid*/
+static int odd_multiplier[9]={
+    5, 7, 9, 11, 12, 13, 1, 3,        
+   21,                                      
+};

should be (13 instead of 12, 15 instead of 13):

+/* translation table for odd multiplier to fid*/
+static int odd_multiplier[9]={
+    5, 7, 9, 11, 13, 15, 1, 3,       
+   21,                                      
+};

A new corrected patch is attached to this mail

Hendrik


[-- Attachment #2: powernow-k7.patch --]
[-- Type: text/x-diff, Size: 9212 bytes --]

--- arch/i386/kernel/cpu/cpufreq/powernow-k7.c.orig     2004-08-14 07:36:12.000000000 +0200
+++ arch/i386/kernel/cpu/cpufreq/powernow-k7.c  2004-10-03 18:20:56.000000000 +0200
@@ -76,28 +76,50 @@
 };
 #endif

-/* divide by 1000 to get VID. */
+/* divide by 1000 to get VCore voltage in V. */
 static int mobile_vid_table[32] = {
     2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
     1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
     1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
-    1075, 1050, 1024, 1000, 975, 950, 925, 0,
+    1075, 1050, 1025, 1000, 975, 950, 925, 0,
 };

-/* divide by 10 to get FID. */
+/* divide by 10 to get multiplier. */
 static int fid_codes[32] = {
     110, 115, 120, 125, 50, 55, 60, 65,
     70, 75, 80, 85, 90, 95, 100, 105,
     30, 190, 40, 200, 130, 135, 140, 210,
-    150, 225, 160, 165, 170, 180, -1, -1,
+    150, 220, 160, 165, 170, 180, -1, -1,
 };

+/* translation table for even multiplier to fid */
+static int even_multiplier[20]= {
+    16, 18,  4,  6,  8, 10, 12, 14,    // 3, 4, 5, 6, 7 ,8 , 9, 10
+     0,  2, 20, 22, 24, 26, 28, 29,    // 11, 12, 13, 14, 15, 16, 17, 18
+    17, 19, 23, 25,                    // 19, 20, 21, 22
+};
+
+/* translation table for odd multiplier to fid*/
+static int odd_multiplier[9]={
+    5, 7, 9, 11, 13, 15, 1, 3,        // 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5
+   21,                                       // 13.5
+};
+
+
 /* This parameter is used in order to force ACPI instead of legacy method for
  * configuration purpose.
  */

 static int acpi_force;

+/* This parameters can be used to manually overwrite the tables */
+static int overwrite_table = 0;
+#define MAX_PST 10
+static int maxPSTSize = MAX_PST;
+static int multiplier[MAX_PST]= {[0 ... (MAX_PST - 1)] = 0};
+static int voltage[MAX_PST]= {[0 ... (MAX_PST - 1)] = 0};
+static int switch_latency=0;
+
 static struct cpufreq_frequency_table *powernow_table;

 static unsigned int can_scale_bus;
@@ -414,6 +436,131 @@
 }
 #endif

+static int powernow_manual_settings(union msr_fidvidstatus *fidvidstatus)
+{
+    int i,k, validentry;
+       unsigned int max_multiplier, max_voltage;
+       unsigned int speed, cm;
+       u8 vid, fid;
+       static struct cpufreq_frequency_table *powernow_table_tmp;
+
+       if (switch_latency > 0) {
+               if (switch_latency < 100) {
+                       printk (KERN_INFO PFX "Settling time passed as %d microseconds."
+                               "Should be at least 100. Correcting.\n", switch_latency);
+                       switch_latency = 100;
+               }
+               latency = switch_latency;
+       } else {
+               latency = 200;
+       }
+       dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", latency);
+
+    /* get number of specified multipliers */
+    for (i=0; i< MAX_PST; i++) {
+        if (multiplier[i] == 0) {
+                       number_scales=i;
+                       break;
+               }
+    }
+
+       /* get maximum values */
+       max_multiplier = fid_codes[fidvidstatus->bits.MFID];
+       max_voltage = mobile_vid_table[fidvidstatus->bits.MVID];
+
+       /* allocate memory */
+       powernow_table=kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+       if (!powernow_table)
+               return -ENOMEM;
+       memset(powernow_table,0,(sizeof(struct cpufreq_frequency_table)*(number_scales+1)));
+
+       k=0;
+       for(i=0; i<number_scales; i++)
+       {
+               validentry = 0;
+               if (multiplier[i] != 0) {
+                       /* fix multiplier */
+                       if (multiplier[i] < 30)
+                               multiplier[i]=multiplier[i] * 10;
+
+                       if (multiplier[i] < max_multiplier) {
+                               cm = (multiplier[i]/10);
+                               /* check if odd or even muliplier */
+                               if (multiplier[i]%10) {
+                                       /* odd multiplier */
+                                       if (cm == 16) {
+                                               /* hardcoded because 14.5 and 15.5 fids not possible */
+                                               fid = 27;
+                                               validentry = 1;
+                                       }else if ((cm > 4) && (cm < 14)) {
+                                               fid= odd_multiplier[cm-5];
+                                               validentry = 1;
+                                       }
+                               } else {
+                                       /* even_multiplier */
+                                       if ((cm < 23) && (cm > 2)) {
+                                               fid = even_multiplier[cm-3];
+                                               validentry=1;
+                                       }
+                               }
+                       }
+               }
+
+               if (validentry) {
+                       /* if no voltage specified use CPU default */
+                       if (voltage[i] == 0)
+                               voltage[i] = max_voltage;
+
+                       /* we do not allow higher voltages than the CPU's maximum
+                       925 mV is the minimum */
+                       if ((voltage[i] <= max_voltage) && (voltage[i] >= 925)) {
+                               if (voltage[i] >= 1300) {
+                                       vid = 40 - (voltage[i]/50);
+                               } else {
+                                       vid = 67 - (voltage[i]/25);
+                               }
+                               /* calculate speed */
+                               speed = fsb * fid_codes[fid] / 10;
+                               powernow_table[k].frequency = speed;
+                               powernow_table[k].index=fid; /*lower 8 bits*/
+                               powernow_table[k].index|= (vid << 8); /*upper 8 bits*/
+
+                               if (speed < minimum_speed)
+                                       minimum_speed = speed;
+                               if (speed > maximum_speed)
+                                       maximum_speed = speed;
+
+                               dprintk (KERN_INFO PFX "   FID: 0x%x (%d.%dx [%dMHz])\t", fid, fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000);
+                               dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000, mobile_vid_table[vid]%1000);
+                               k++;
+                       }
+               } else {
+                       // invalid entry
+                       dprintk (KERN_INFO PFX "Entry %d is invalid\n", i+1);
+               }
+       }
+
+       if (k < number_scales) {
+               /* some entrys were invalid need to realloc table */
+               number_scales = k;
+               powernow_table_tmp = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+               if (!powernow_table_tmp) {
+                       kfree(powernow_table);
+                       return -ENOMEM;
+                       }
+               memcpy(powernow_table_tmp,powernow_table,(sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));
+               kfree(powernow_table);
+               powernow_table=powernow_table_tmp;
+       }
+
+
+       /* Terminate frequency list */
+       powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
+       powernow_table[number_scales].index = 0;
+
+       return 0;
+}
+
 static int powernow_decode_bios (int maxfid, int startvid)
 {
        struct psb_s *psb;
@@ -601,6 +748,11 @@
        if (dmi_check_system(powernow_dmi_table) || acpi_force) {
                printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
                result = powernow_acpi_init();
+        }
+        else if (overwrite_table){
+            printk(KERN_INFO PFX "Overwriting PST table with manual settings\n");
+            result = powernow_manual_settings(&fidvidstatus);
+
        } else {
                result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
                if (result) {
@@ -681,6 +833,14 @@

 module_param(acpi_force,  int, 0444);
 MODULE_PARM_DESC(acpi_force, "Force ACPI to be used");
+module_param(overwrite_table,int,0444);
+MODULE_PARM_DESC(overwrite_table, "overwrite table with manually settings");
+module_param_array(multiplier, int, maxPSTSize, 0444);
+MODULE_PARM_DESC(multiplier, "Specifiy up to 10 multipliers, multiply them by 10: 5->50, 5.5->55");
+module_param_array(voltage, int, maxPSTSize, 0444);
+MODULE_PARM_DESC(voltage, "Specify voltages in respect to the given multipliers, specify them in mV: 1.275V -> 1275");
+module_param(switch_latency,  int, 0444);
+MODULE_PARM_DESC(switch_latency, "Set state transition latency in microseconds (default 200us)");

 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
@@ -688,4 +848,3 @@

 late_initcall(powernow_init);
 module_exit(powernow_exit);
-

[-- Attachment #3: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Cpufreq mailing list
Cpufreq@www.linux.org.uk
http://www.linux.org.uk/mailman/listinfo/cpufreq

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2005-01-19 15:35 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-12  8:18 [PATCH] Another powernow-k7 patch for Desktop XP-M usage Hendrik Muhs
2004-10-14 23:26 ` Nebojsa Trpkovic
2004-10-20  9:43   ` Bruno Ducrot
2004-10-20 22:05     ` Harald Milz
2004-10-21  0:56     ` Nebojsa Trpkovic
2004-10-15  7:05 Hendrik Muhs
2004-10-15 22:28 ` Nebojsa Trpkovic
2004-11-29 21:36   ` Nebojsa Trpkovic
2004-10-16 16:11 ` mark newman
2005-01-14 11:46 ` Jarkko Lavinen
2005-01-17 15:21   ` Hendrik Muhs
2005-01-17 16:31     ` Jarkko Lavinen
2005-01-19 15:35     ` Jarkko Lavinen
2004-12-01 20:09 Hendrik Muhs

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.