All of lore.kernel.org
 help / color / mirror / Atom feed
* Custom powerstates table in powernow-K7 ?
  2004-12-18 21:24 [ANNOUNCE] cpufrequtils-0.1 released Harald Milz
@ 2004-12-19 10:57 ` Alex Simonov
  2004-12-20 12:50   ` Bruno Ducrot
  0 siblings, 1 reply; 3+ messages in thread
From: Alex Simonov @ 2004-12-19 10:57 UTC (permalink / raw)
  To: cpufreq

Hi all,

Is there any simple way to use the powernow-k7
driver with custom PST? Until now (kernel 2.6.3)
I've always used to patch the module, hardwiring
my own PST table for my Mobile Athlon XP 1900+,
but with 2.6.8 kernels it seems more complex,
with all this ACPI stuff added to it. It is not
enough anymore to patch the 
powernow_decode_bios (int maxfid, int startvid)
function any more ..:(

Could you give me some hints please? May be there
is opportunity to pass it as a parameter to the
cpufreq module? Or a way to integrate it in the
initrd.img?


Thanks a lot in advance,

Alex


		
__________________________________ 
Do you Yahoo!? 
Read only the mail you want - Yahoo! Mail SpamGuard. 
http://promotions.yahoo.com/new_mail 

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

* Re: Custom powerstates table in powernow-K7 ?
  2004-12-19 10:57 ` Custom powerstates table in powernow-K7 ? Alex Simonov
@ 2004-12-20 12:50   ` Bruno Ducrot
  0 siblings, 0 replies; 3+ messages in thread
From: Bruno Ducrot @ 2004-12-20 12:50 UTC (permalink / raw)
  To: Alex Simonov; +Cc: cpufreq

On Sun, Dec 19, 2004 at 02:57:43AM -0800, Alex Simonov wrote:
> Hi all,
> 
> Is there any simple way to use the powernow-k7
> driver with custom PST? Until now (kernel 2.6.3)
> I've always used to patch the module, hardwiring
> my own PST table for my Mobile Athlon XP 1900+,
> but with 2.6.8 kernels it seems more complex,
> with all this ACPI stuff added to it. It is not
> enough anymore to patch the 
> powernow_decode_bios (int maxfid, int startvid)
> function any more ..:(

At first, are you sure going with ACPI didn't help?  If that is the
case, I don't see the difficulty to do what you ask, especially if you
have already done such hack (ACPI is a fallback, so unless your laptop
is in a DMI blacklist, hacking powernow_decode_bios() should work).

> Could you give me some hints please? May be there
> is opportunity to pass it as a parameter to the
> cpufreq module? Or a way to integrate it in the
> initrd.img?

I'm afraid nobody will integrate that in mainline.

Cheers,

-- 
Bruno Ducrot

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

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

* Re: Custom powerstates table in powernow-K7 ?
@ 2004-12-20 15:05 Nebojsa Trpkovic
  0 siblings, 0 replies; 3+ messages in thread
From: Nebojsa Trpkovic @ 2004-12-20 15:05 UTC (permalink / raw)
  To: cpufreq

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

Here is patch I have used with my Barton moded to mobile. I was
succesful at using multiplicators such as 5, 6, 7, 8, 9 and 10.5. I have
a little bit of trouble with 3, 4 and 11.
Patch is writen by member of this list, and I just can't recall his
name. Maybe you could look back in october/november mails to find out.

You must compile it as a module and load it with line similar to this:

modprobe powernow-k7 overwrite_table=1 multiplier=50,60,70,80,90,105
switch_latency=650

Try chinging switch_latency. I give you no worranty to your hardware :D


Patch is attached. I think it was writen for 2.6.7, but I've used it on
2.6.8 and 2.6.9 as well (manual patching). As powernow-k7.c differs from
kernel to kernel you will porbably have to insert those lines manualy
where they belong:




[-- Attachment #2: powernow-k7.patch --]
[-- Type: text/plain, Size: 9213 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] 3+ messages in thread

end of thread, other threads:[~2004-12-20 15:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-20 15:05 Custom powerstates table in powernow-K7 ? Nebojsa Trpkovic
  -- strict thread matches above, loose matches on Subject: below --
2004-12-18 21:24 [ANNOUNCE] cpufrequtils-0.1 released Harald Milz
2004-12-19 10:57 ` Custom powerstates table in powernow-K7 ? Alex Simonov
2004-12-20 12:50   ` Bruno Ducrot

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.