Skip to contentSkip to conversation

powernow-k8 updates

PATCH Pavel Machek 3 participants 6 messages Mar 9, 2004 – Mar 14, 2004

lore
Share & tools
lore
#0 lore raw

Hi!

This adds powernow-k8-acpi driver, which likes on more machines than powernow-k8, but depends on acpi. I'd like to get this into 2.6.5... Does it look okay?

Also if you have problems with your eMachines cpufreq, apply this and switch to -acpi driver. It should fix it for you.
Pavel

arch/i386/kernel/cpu/cpufreq/Kconfig +13 -0
@@ -93,6 +93,19 @@
 	depends on CPU_FREQ && EXPERIMENTAL
 	help
 	  This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
+	  It relies on old "PST" tables. Unfortunately, many BIOSes get this table
+	  wrong. 
+
+	  For details, take a look at linux/Documentation/cpu-freq. 
+
+	  If in doubt, say N.
+
+config X86_POWERNOW_K8_ACPI
+	tristate "AMD Opteron/Athlon64 PowerNow! using ACPI"
+	depends on CPU_FREQ && EXPERIMENTAL
+	help
+	  This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
+	  It relies on ACPI.
 
 	  For details, take a look at linux/Documentation/cpu-freq. 
 
arch/i386/kernel/cpu/cpufreq/Makefile +1 -0
@@ -1,6 +1,7 @@
 obj-$(CONFIG_X86_POWERNOW_K6)	+= powernow-k6.o
 obj-$(CONFIG_X86_POWERNOW_K7)	+= powernow-k7.o
 obj-$(CONFIG_X86_POWERNOW_K8)	+= powernow-k8.o
+obj-$(CONFIG_X86_POWERNOW_K8_ACPI)	+= powernow-k8-acpi.o
 obj-$(CONFIG_X86_LONGHAUL)	+= longhaul.o
 obj-$(CONFIG_X86_P4_CLOCKMOD)	+= p4-clockmod.o
 obj-$(CONFIG_ELAN_CPUFREQ)	+= elanfreq.o
arch/i386/kernel/cpu/cpufreq/powernow-k8-acpi.c +987 -0

987 lines not on this page · raw message

arch/i386/kernel/cpu/cpufreq/powernow-k8.c +143 -402

778 lines not on this page · raw message

Only in linux/arch/i386/kernel/cpu/cpufreq: powernow-k8.c-new

arch/i386/kernel/cpu/cpufreq/powernow-k8.h +318 -66

440 lines not on this page · raw message

Signature · 2 lines
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]
#1 lore raw
Quoted 17 lines · Pavel Machek

Hi!

This adds powernow-k8-acpi driver, which likes on more machines than powernow-k8, but depends on acpi. I'd like to get this into 2.6.5... Does it look okay?

Also if you have problems with your eMachines cpufreq, apply this and switch to -acpi driver. It should fix it for you.
Pavel

arch/i386/kernel/cpu/cpufreq/Kconfig +0 -0
@@ -93,6 +93,19 @@
 	depends on CPU_FREQ && EXPERIMENTAL
 	help
 	  This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.

arch/i386/kernel/cpu/cpufreq/Kconfig line 105

Quoted 10 lines
arch/i386/kernel/cpu/cpufreq/Kconfig +10 -0
+	  It relies on old "PST" tables. Unfortunately, many BIOSes get this table
+	  wrong. 
+
+	  For details, take a look at linux/Documentation/cpu-freq. 
+
+	  If in doubt, say N.
+
+config X86_POWERNOW_K8_ACPI
+	tristate "AMD Opteron/Athlon64 PowerNow! using ACPI"
+	depends on CPU_FREQ && EXPERIMENTAL

Why there is no dependency with ACPI here?

...

Quoted 7 lines
arch/i386/kernel/cpu/cpufreq/powernow-k8-acpi.c +4 -0
@@ -0,0 +1,987 @@
+/*
+ *   (c) 2003, 2004 Advanced Micro Devices, Inc.
+ *  Your use of this code is subject to the terms and conditions of the
+ *  GNU general public license version 2. See COPYING or

...

Quoted 5 lines

+/*
+ * Each processor may have
+ * a different number of entries in its array. I.e., processor 0 may have
+ * 3 pstates, processor 1 may have 5 pstates.
+ */

No. That will break current ACPI v2.0c specification. All processors shall have the same number of states. More, they have to support the same set of pairs of frequency/power consuption.

If that is not acceptable by AMD, then you have to contact ACPI SIG at <http://www.acpi.info/> in order to change specs.

...

For the last time, why on earth you still do not consider the ACPI perflib. Links to the cpufreq-developper mailing list with even a kind of public access have been posted. That will eliminate the following functions amongst other things. Look at drivers/acpi/processor.c

Quoted 60 lines
arch/i386/kernel/cpu/cpufreq/powernow-k8-acpi.c +60 -0
+static u32 query_ac(void)
+{
+	acpi_status rc;
+	unsigned long state;
+
+	if (psrh) {
+		rc = acpi_evaluate_integer(psrh, NULL, NULL, &state);
+		if (ACPI_SUCCESS(rc)) {
+			if (state == 1)
+				return POW_AC;
+			else if (state == 0)
+				return POW_BAT;
+			else
+				printk(EFX "psr state %lx\n", state);
+		}
+		else {
+			printk(EFX "error %x evaluating psr\n", rc );
+		}
+	}
+	return POW_UNK;
+}
+
+/* gives us the (optional) battery/thermal restrictions */
+static int process_ppc(acpi_handle objh)
+{
+	acpi_status rc;
+	unsigned long state;
+
+	if (objh) {
+		ppch = objh;
+	} else {
+		if (ppch) {
+			objh = ppch;
+		} else {
+			rstps = 0;
+			return 0;   
+		}
+	}
+
+	if (num_online_cpus() > 1) {
+		/* For future thermal support (next release?), rstps needs   */
+		/* to be per processor, and handled for the SMP case. Later. */
+		dprintk(EFX "ignoring attempt to restrict pstates for SMP\n");
+	}
+	else {
+		rc = acpi_evaluate_integer(objh, NULL, NULL, &state);
+		if (ACPI_SUCCESS(rc)) {
+			rstps = state & 0x0f;
+			//dprintk(DFX "pstate restrictions %x\n", rstps);
+			if (!seenrst)
+				seenrst = rstps;
+		}
+		else {
+			rstps = 0;
+			printk(EFX "error %x processing ppc\n", rc);
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
Signature · 4 lines
Bruno Ducrot

--  Which is worse:  ignorance or apathy?
--  Don't know.  Don't care.
#2 lore raw

Hi!

Quoted 10 lines
Quoted 10 lines
arch/i386/kernel/cpu/cpufreq/Kconfig +4 -0
@@ -93,6 +93,19 @@
 	depends on CPU_FREQ && EXPERIMENTAL
 	help
 	  This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
+	  It relies on old "PST" tables. Unfortunately, many BIOSes get this table
+	  wrong. 
+
+	  For details, take a look at linux/Documentation/cpu-freq. 
Quoted 8 lines

arch/i386/kernel/cpu/cpufreq/Kconfig line 105

Quoted 6 lines
arch/i386/kernel/cpu/cpufreq/Kconfig +6 -0
+
+	  If in doubt, say N.
+
+config X86_POWERNOW_K8_ACPI
+	tristate "AMD Opteron/Athlon64 PowerNow! using ACPI"
+	depends on CPU_FREQ && EXPERIMENTAL

Why there is no dependency with ACPI here?

I'll fix that.

Quoted 6 lines

arch/i386/kernel/cpu/cpufreq/Kconfig line 110

Quoted 5 lines
arch/i386/kernel/cpu/cpufreq/Kconfig +5 -0
+/*
+ * Each processor may have
+ * a different number of entries in its array. I.e., processor 0 may have
+ * 3 pstates, processor 1 may have 5 pstates.
+ */
Quoted 6 lines

No. That will break current ACPI v2.0c specification. All processors shall have the same number of states. More, they have to support the same set of pairs of frequency/power consuption.

If that is not acceptable by AMD, then you have to contact ACPI SIG at <http://www.acpi.info/> in order to change specs.

Notice that amd's powernow is done through acpi, but does not comply to the acpi specs. That should be okay; in such case its up to AMD to define how it behaves.

Quoted 4 lines

For the last time, why on earth you still do not consider the ACPI perflib. Links to the cpufreq-developper mailing list with even a kind of public access have been posted. That will eliminate the following functions amongst other things. Look at drivers/acpi/processor.c

I see that file. It seems to be full of northbridge bugs workarounds, and seems to be handling processor C states. It handles powernow states on machines that do it through acpi. I do not see how I could use it, and I do not see how query_ac could disappear. It might be nice to use same processor/.../performance interface, but it is deprecated anyway.

What do I miss?

Quoted 61 lines
Quoted 60 lines
arch/i386/kernel/cpu/cpufreq/Kconfig +60 -0
+static u32 query_ac(void)
+{
+	acpi_status rc;
+	unsigned long state;
+
+	if (psrh) {
+		rc = acpi_evaluate_integer(psrh, NULL, NULL, &state);
+		if (ACPI_SUCCESS(rc)) {
+			if (state == 1)
+				return POW_AC;
+			else if (state == 0)
+				return POW_BAT;
+			else
+				printk(EFX "psr state %lx\n", state);
+		}
+		else {
+			printk(EFX "error %x evaluating psr\n", rc );
+		}
+	}
+	return POW_UNK;
+}
+
+/* gives us the (optional) battery/thermal restrictions */
+static int process_ppc(acpi_handle objh)
+{
+	acpi_status rc;
+	unsigned long state;
+
+	if (objh) {
+		ppch = objh;
+	} else {
+		if (ppch) {
+			objh = ppch;
+		} else {
+			rstps = 0;
+			return 0;   
+		}
+	}
+
+	if (num_online_cpus() > 1) {
+		/* For future thermal support (next release?), rstps needs   */
+		/* to be per processor, and handled for the SMP case. Later. */
+		dprintk(EFX "ignoring attempt to restrict pstates for SMP\n");
+	}
+	else {
+		rc = acpi_evaluate_integer(objh, NULL, NULL, &state);
+		if (ACPI_SUCCESS(rc)) {
+			rstps = state & 0x0f;
+			//dprintk(DFX "pstate restrictions %x\n", rstps);
+			if (!seenrst)
+				seenrst = rstps;
+		}
+		else {
+			rstps = 0;
+			printk(EFX "error %x processing ppc\n", rc);
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
Signature · 2 lines
Horseback riding is like software...
...vgf orggre jura vgf serr.
#3 lore raw
Quoted 6 lines · Pavel Machek
Quoted 2 lines

If that is not acceptable by AMD, then you have to contact ACPI SIG at <http://www.acpi.info/> in order to change specs.

Notice that amd's powernow is done through acpi, but does not comply to the acpi specs. That should be okay; in such case its up to AMD to define how it behaves.

Yes, but then, I think that AMD shall contact ACPI SIG in order to change specs, or even becoming member of ACPI SIG.

Note that currently drivers/acpi/processor.c do not check the requirement to have the exact same number of pstates for each processor. I don't think that nobody want to fix that btw ;)

Quoted 5 lines
Quoted 4 lines

For the last time, why on earth you still do not consider the ACPI perflib. Links to the cpufreq-developper mailing list with even a kind of public access have been posted. That will eliminate the following functions amongst other things. Look at drivers/acpi/processor.c

Quoted 8 lines

I see that file. It seems to be full of northbridge bugs workarounds, and seems to be handling processor C states. It handles powernow states on machines that do it through acpi. I do not see how I could use it, and I do not see how query_ac could disappear. It might be nice to use same processor/.../performance interface, but it is deprecated anyway.

What do I miss?

ducrot@poupon:~/kernel/linux-2.6.4-bk-acpi> grep EXPORT drivers/acpi/processor.c EXPORT_SYMBOL(acpi_processor_register_performance); EXPORT_SYMBOL(acpi_processor_unregister_performance); EXPORT_SYMBOL(acpi_processor_set_thermal_limit);

So all you need are acpi_processor_register_performance() and acpi_processor_unregister_performance(). I'm pretty sure that those functions are in 2.6.4-rc2.

If you want to play with those functions, you have to include <acpi/processor.h>, and then you have to register a driver via:
acpi_processor_register_performance(&pr, cpu) where:
- cpu is the cpu id (point-of-view of Linux, not the acpi cpu id),
- pr is a struct acpi_processor_performance (defined in acpi/processor.h).

You will have then for free:
- configurations via the acpi_processor_performance structure,
- handling of the _PPC object, so that you don't have to care about changes for that in the driver. That will be done via classic ACPI event notifications to the processor, via the limit interface writen in drivers/acpi/processor.c, and cpufreq notion of notifiers.

More, you do not have to worry about ACPI initialisation. At that time, the powernow-k8 acpi driver do not even check if ACPI is initialised, or up and running, etc, like it is done in the sonypi driver for example.

If you want examples, there were posts for the centrino case, and for the powernow-k7, in cpufreq mailing lists.

I used also that stupid module, an hack of an example provided by Dominik, in order to write the support for the powernow-k7.

Cheers,

Signature · 4 lines
Bruno Ducrot

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

/*
*/

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/uaccess.h>

#include <linux/acpi.h>
#include <acpi/processor.h>

struct acpi_processor_performance p;

union powernow_acpi_control_t {
	struct {
		unsigned long fid:5,
		vid:5,
		sgtc:20,
		res1:2;
	} bits;
	unsigned long val;
};

#define ACPI_PDC_REVISION_ID 0x1
#define ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP 0x1

static int __init
acpi_cpufreq_init (void)

{
	unsigned int i;
	struct acpi_pct_register *r;
	union powernow_acpi_control_t pc;

	if (acpi_processor_register_performance(&p, 0))
		return -EIO;

	printk("number of states: %d\n", p.state_count);
	for (i=0; i< p.state_count; i++) {
		pc.val = (unsigned long) p.states[i].control;
		printk(KERN_INFO "powernow: %cP%d: %d MHz, %d mW, %d uS, control %08x, status %08x, vid: %02x fid: %02x SGTC: %d\n",
		       (i == p.state?'*':' '), i,
		       (u32) p.states[i].core_frequency,
		       (u32) p.states[i].power,
		       (u32) p.states[i].transition_latency,
		       (u32) p.states[i].control,
		       (u32) p.states[i].status,
		       pc.bits.vid,
		       pc.bits.fid,
		       pc.bits.sgtc);

	}

	printk("control_register:\n");
	r = &p.control_register;
	printk("%d %d %d %d %d %d %lld\n", r->descriptor, r->length, r->space_id,
	       r->bit_width, r->bit_offset, r->reserved, r->address);

	printk("status_register:\n");
	r = &p.status_register;
	printk("%d %d %d %d %d %d %lld\n", r->descriptor, r->length, r->space_id,
	       r->bit_width, r->bit_offset, r->reserved, r->address);

	acpi_processor_unregister_performance(&p, 0);

	return -ENODEV;
}

static void __exit
acpi_cpufreq_exit (void)

{
	return;
}

late_initcall(acpi_cpufreq_init);
module_exit(acpi_cpufreq_exit);

_______________________________________________
Cpufreq mailing list
[email protected]
http://www.linux.org.uk/mailman/listinfo/cpufreq

#4 lore raw
Quoted 8 lines · Bruno Ducrot

ducrot@poupon:~/kernel/linux-2.6.4-bk-acpi> grep EXPORT drivers/acpi/processor.c EXPORT_SYMBOL(acpi_processor_register_performance); EXPORT_SYMBOL(acpi_processor_unregister_performance); EXPORT_SYMBOL(acpi_processor_set_thermal_limit);

So all you need are acpi_processor_register_performance() and acpi_processor_unregister_performance(). I'm pretty sure that those functions are in 2.6.4-rc2.

These functions are indeed in 2.6.3 and 2.6.4 -- and they work fine. If you have any questions related to them, please ask me.

Quoted 7 lines

If you want to play with those functions, you have to include <acpi/processor.h>, and then you have to register a driver via:
acpi_processor_register_performance(&pr, cpu) where:
- cpu is the cpu id (point-of-view of Linux, not the acpi cpu id),
- pr is a struct acpi_processor_performance (defined in acpi/processor.h).

Quoted 6 lines

You will have then for free:
- configurations via the acpi_processor_performance structure,
- handling of the _PPC object, so that you don't have to care about changes for that in the driver. That will be done via classic ACPI event notifications to the processor, via the limit interface writen in drivers/acpi/processor.c, and cpufreq notion of notifiers.

Minor correction: only the first and last steps are indeed used to handle _PPC, IIRC.

Also, you'll have
- support for _PDC, if needed
- proper embedding into ACPI core
- the /proc/acpi/processor/./performance interface which some still tend to like...

Dominik

_______________________________________________
Cpufreq mailing list
[email protected]
http://www.linux.org.uk/mailman/listinfo/cpufreq

#5 lore raw
In reply to Pavel Machek
Quoted 2 lines · Pavel Machek

[Is it okay to post it to the lists for more testing and/or inclusion?]

I prefer patches to files to comment on.

arch/i386/kernel/cpu/cpufreq/Kconfig line 105

Quoted 3 lines
arch/i386/kernel/cpu/cpufreq/Kconfig +3 -0
+config X86_POWERNOW_K8_ACPI
+     tristate "AMD Opteron/Athlon64 PowerNow! using ACPI"
+     depends on CPU_FREQ && EXPERIMENTAL

depends on ... && ACPI ?

See also the other mail discussing how to handle the two methods to detect speed.

Unfortunately, I consider this new ACPI driver to be in an "unmergeable" state, as the extra "polling" is unneccessary if the ACPI perflib is used, the extra parsing of ACPI tables can fail much too easily, and the whole driver is too fragile with regard to ACPI interaction.

Dominik

_______________________________________________
Cpufreq mailing list
[email protected]
http://www.linux.org.uk/mailman/listinfo/cpufreq