7.10 support of new AMD PowerNow! (family 0x11 and beyond)

Mark Langsdorf mark.langsdorf at amd.com
Thu Jan 24 16:10:40 UTC 2008


On Thursday 24 January 2008, Matt_Domsch at dell.com wrote:
> Copying Amit and Jose who were paying the most attention to such.
> 
> --
> Matt Domsch
> Linux Technology Strategist, Dell Office of the CTO
> linux.dell.com & www.dell.com/linux
> 
> 
> -----Original Message-----
> From: Tim Gardner [mailto:tim.gardner at canonical.com] 
> Sent: Thursday, January 24, 2008 9:44 AM
> To: Langsdorf, Mark; Domsch, Matt
> Cc: kernel-team at lists.ubuntu.com
> Subject: Re: 7.10 support of new AMD PowerNow! (family 0x11 and beyond)
> 
> Langsdorf, Mark wrote:
> >>> In late November, I submitted a few patches to this list
> >>> for consideration in an Ubuntu 7.10 update release.  The
> >>> purpose was to provide support for PowerNow! in AMD's
> >>> forthcoming Family 0x11 processors.  There was a short
> >>> patch submittted on 11/27 that addressed Family 0x11
> >>> parts, and a much larger patch on 11/29 that handled all
> >>> future AMD parts.
> >>>
> >>> There was never much discussion of them that I saw, and
> >>> so I don't know which, if either, was adapted.  Linux
> >>> PowerNow! support of family 0x11 parts is becoming 
> >>> important to some of our OEMs, so I'm trying to determine
> >>> what the Ubuntu kernel community did.  Would someone 
> >>> please enlighten me?
> >>>   
> >>>       
> >> Mark - We have reviewed the November patch, but see some problems
> with
> >> it. It appears to change the default behavior of the 
> >> function, which we are loath to do in a security update.
> >>     
> >
> > There were 2 November patches: a small one that addresses 0x11
> > only, and a larger one that addresses all future families.
> >
> > I'm not sure how either patch changes the default behavior.
> > Would you explain?
> >
> > * The small patch adjusts the calculation of frequency from
> > the Frequency ID based on the family number.  This is necessary
> > to get PowerNow! working on 0x11 parts, since the 0x10 calculation
> > returns the incorrect frequency and the driver assumes there is
> > an ACPI error.
> >
> > * The large patch removes Frequency ID (fid) from the driver 
> > altogether, because fid is not part of the architectural
> > definition and is not guaranteed to be supported on future
> > parts.
> >
> >   
> >> I also do not see this patch upstream in 2.6.24-rc8. Why not?
> >>     
> >
> > The small one was superceded by the large patch.  The majority
> > of the large patch code (and the more relevant portion) is in
> > 2.6.24-rc8 as far as I can tell.  I'll go nag Dave Jones about
> > getting the rest of the patch in.  The full patch is in
> > 2.6.24-rc8-mm1.

> >   
> Mark - I've applied the small patch, but it appears the larger patch
> that you mentioned was not submitted to the mailing list. I have it

Strange.  I have the outbound email for it. Resubmitting below.

> indirectly from Matt Domsch (and others) that the frequency calculation
> patch is the right thing to do. This change will show up only in the
> Gutsy security update kernel.

Good enough, but I'll include the large patch in case you want to
review it.

-Mark Langsdorf
Operating System Research Center
AMD

Full patch: 

This patch merges several individual patches that have gone into
either linux-2.6.24-rc3 or linux-2.6.24-rc3-mm2.

The initial implementation of the hardware pstate driver for PowerNow!
used some processor-version specific features, and would not be
maintainable in the long term as the processor features changed.
This architectural driver should work on all future AMD processors.
This patch changes the powernow-k8 driver code that deals with 3rd 
generation Opteron, Phenom, and later processors to match the 
architectural pstate driver described in the AMD64 Architecture 
Programmer's Manual Volume 2 Chapter 18.  

It also adds support for the ACPI _PSD structure, which indicates 
which processors have their pstates tied together.  _PSD discovery 
is handled through acpi_processor_preregister_performance().  
Fallback support is included if the BIOS does not provide a _PSD.




--- linux-2.6.22/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2007-07-08 18:32:17.000000000 -0500
+++ mm2-linux-2.6.24-rc3/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2007-11-29 09:44:24.000000000 -0600
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/cpumask.h>
@@ -46,7 +47,7 @@
 
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 2.00.00"
+#define VERSION "version 2.20.00"
 #include "powernow-k8.h"
 
 /* serialize freq changes  */
@@ -57,7 +58,7 @@ static struct powernow_k8_data *powernow
 static int cpu_family = CPU_OPTERON;
 
 #ifndef CONFIG_SMP
-static cpumask_t cpu_core_map[1];
+DEFINE_PER_CPU(cpumask_t, cpu_core_map);
 #endif
 
 /* Return a frequency in MHz, given an input fid */
@@ -73,30 +74,11 @@ static u32 find_khz_freq_from_fid(u32 fi
 	return 1000 * find_freq_from_fid(fid);
 }
 
-/* Return a frequency in MHz, given an input fid and did */
-static u32 find_freq_from_fiddid(u32 fid, u32 did)
+static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate)
 {
-	return 100 * (fid + 0x10) >> did;
+	return data[pstate].frequency;
 }
 
-static u32 find_khz_freq_from_fiddid(u32 fid, u32 did)
-{
-	return 1000 * find_freq_from_fiddid(fid, did);
-}
-
-static u32 find_fid_from_pstate(u32 pstate)
-{
-	u32 hi, lo;
-	rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
-	return lo & HW_PSTATE_FID_MASK;
-}
-
-static u32 find_did_from_pstate(u32 pstate)
-{
-	u32 hi, lo;
-	rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
-	return (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
-}
 
 /* Return the vco fid for an input fid
  *
@@ -139,13 +121,12 @@ static int query_current_values_with_pen
 	if (cpu_family == CPU_HW_PSTATE) {
 		rdmsr(MSR_PSTATE_STATUS, lo, hi);
 		i = lo & HW_PSTATE_MASK;
-		rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi);
-		data->currfid = lo & HW_PSTATE_FID_MASK;
-		data->currdid = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
+		data->currpstate = i;
 		return 0;
 	}
 	do {
-		if (i++ > 10000) {
+		msleep(5);
+		if (i++ > 1000) {
 			dprintk("detected change pending stuck\n");
 			return 1;
 		}
@@ -165,7 +146,7 @@ static void count_off_irt(struct powerno
 	return;
 }
 
-/* the voltage stabalization time */
+/* the voltage stabilization time */
 static void count_off_vst(struct powernow_k8_data *data)
 {
 	udelay(data->vstable * VST_UNITS_20US);
@@ -292,7 +273,7 @@ static int decrease_vid_code_by_step(str
 static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
 {
 	wrmsr(MSR_PSTATE_CTRL, pstate, 0);
-	data->currfid = find_fid_from_pstate(pstate);
+	data->currpstate = pstate;
 	return 0;
 }
 
@@ -599,14 +580,16 @@ static void print_basics(struct powernow
 	for (j = 0; j < data->numps; j++) {
 		if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) {
 			if (cpu_family == CPU_HW_PSTATE) {
-			printk(KERN_INFO PFX "   %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8,
-				(data->powernow_table[j].index & 0xff0000) >> 16,
-				data->powernow_table[j].frequency/1000);
+				printk(KERN_INFO PFX "   %d : pstate %d (%d MHz)\n",
+					j,
+					data->powernow_table[j].index,
+					data->powernow_table[j].frequency/1000);
 			} else {
-			printk(KERN_INFO PFX "   %d : fid 0x%x (%d MHz), vid 0x%x\n", j,
-				data->powernow_table[j].index & 0xff,
-				data->powernow_table[j].frequency/10






More information about the kernel-team mailing list