All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dominik Brodowski <linux@brodo.de>
To: David Moore <dcm@acm.org>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>,
	Ducrot Bruno <ducrot@poupinou.org>,
	Andrew Grover <andrew.grover@intel.com>,
	cpufreq list <cpufreq@www.linux.org.uk>,
	"Adachi, Kenichi" <adachi@rd.scei.sony.co.jp>,
	acpi-devel@lists.sourceforge.net
Subject: [RFC] cpufreq: use new acpi processor perflib in speedstep-centrino [Was: Re: [ACPI] _PDC method in DSDT]
Date: Fri, 5 Sep 2003 01:19:32 +0200	[thread overview]
Message-ID: <20030904231932.GA8518@brodo.de> (raw)
In-Reply-To: <1056491271.3979.15.camel@aldebaran.caltech.edu>

This patch modifies the speedstep-centrino driver to use the ACPI 
processor perflib if no hardcoded value could be found. Centrino-specific
stuff is taken from a patch to arch/i386/kernel/cpu/cpufreq/acpi.c by 
David Moore [in this thread].

 arch/i386/kernel/cpu/cpufreq/Kconfig              |   14 +++
 arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c |   88 ++++++++++++++++++----
2 files changed, 89 insertions(+), 13 deletions(-)

diff -ruN linux-original/arch/i386/kernel/cpu/cpufreq/Kconfig linux/arch/i386/kernel/cpu/cpufreq/Kconfig
--- linux-original/arch/i386/kernel/cpu/cpufreq/Kconfig	2003-09-04 21:36:58.000000000 +0200
+++ linux/arch/i386/kernel/cpu/cpufreq/Kconfig	2003-09-05 01:13:44.374639488 +0200
@@ -113,6 +113,20 @@
 	  
 	  If in doubt, say N.
 
+config X86_SPEEDSTEP_CENTRINO_ACPI
+	bool "Fall back to ACPI tables info"
+	depends on X86_SPEEDSTEP_CENTRINO && ACPI_PROCESSOR_PERFLIB
+	default n
+	help
+	  If your Intel Pentium M (Centrino) CPU is so new that
+	  it cannot be found yet by the Intel Enhanced SpeedStep
+	  CPUfreq driver, you might want to try enabling this option.
+
+	  It reads out the ACPI tables trying to determine the correct
+	  settings.
+	  
+	  If in doubt, say N.
+
 config X86_SPEEDSTEP_LIB
        tristate
        depends on X86_SPEEDSTEP_ICH
diff -ruN linux-original/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
--- linux-original/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2003-09-04 20:52:48.000000000 +0200
+++ linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2003-09-05 01:13:55.006023272 +0200
@@ -37,6 +37,7 @@
 #define dprintk(msg...) do { } while(0)
 #endif
 
+
 struct cpu_model
 {
 	const char	*model_name;
@@ -46,7 +47,7 @@
 };
 
 /* Operating points for current CPU */
-static const struct cpu_model *centrino_model;
+static struct cpufreq_frequency_table *centrino_table;
 
 /* Computes the correct form for IA32_PERF_CTL MSR for a particular
    frequency/voltage operating point; frequency in MHz, volts in mV.
@@ -196,7 +197,7 @@
 {
 	unsigned freq;
 
-	if (policy->cpu != 0 || centrino_model == NULL)
+	if (policy->cpu != 0 || centrino_table == NULL)
 		return -ENODEV;
 
 	freq = get_cur_freq();
@@ -207,8 +208,8 @@
 
 	dprintk(KERN_INFO PFX "centrino_cpu_init: policy=%d cur=%dkHz\n",
 		policy->policy, policy->cur);
-	
-	return cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
+
+	return cpufreq_frequency_table_cpuinfo(policy, centrino_table);
 }
 
 /**
@@ -220,7 +221,7 @@
  */
 static int centrino_verify (struct cpufreq_policy *policy)
 {
-	return cpufreq_frequency_table_verify(policy, centrino_model->op_points);
+	return cpufreq_frequency_table_verify(policy, centrino_table);
 }
 
 /**
@@ -237,14 +238,14 @@
 	unsigned int	msr, oldmsr, h;
 	struct cpufreq_freqs	freqs;
 
-	if (centrino_model == NULL)
+	if (centrino_table == NULL)
 		return -ENODEV;
 
-	if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
+	if (cpufreq_frequency_table_target(policy, centrino_table, target_freq,
 					   relation, &newstate))
 		return -EINVAL;
 
-	msr = centrino_model->op_points[newstate].index;
+	msr = centrino_table[newstate].index;
 	rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
 
 	if (msr == (oldmsr & 0xffff))
@@ -293,6 +294,63 @@
 	.owner		= THIS_MODULE,
 };
 
+#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+
+#define ACPI_PDC_REVISION_ID			0x1
+#define ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP	0x1
+
+static struct cpufreq_frequency_table * get_frequency_table_from_acpi(void) 
+{
+	union acpi_object		arg0 = {ACPI_TYPE_BUFFER};
+	u32				arg0_buf[3];
+	struct acpi_object_list		arg_list = {1, &arg0};
+	struct acpi_perflib_driver	perflib_driver;
+	struct acpi_perflib_data 	*data;
+	struct cpufreq_frequency_table	*table = NULL;
+	int				i;
+
+	/* First call _PDC, if available, to indicate to ACPI that this
+	 * driver supports Enhanced Speedstep.
+	 * Documentation for the _PDC method is at:
+	 * http://www.microsoft.com/whdc/hwdev/tech/onnow/procperfctrl.mspx */
+	arg0.buffer.length = 12;
+	arg0.buffer.pointer = (u8 *) arg0_buf;
+	arg0_buf[0] = ACPI_PDC_REVISION_ID;
+	arg0_buf[1] = 1;
+	arg0_buf[2] = ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP;
+
+	perflib_driver.pdc = &arg_list;
+
+	data = acpi_processor_perflib_register(&perflib_driver, 0);
+	if (!data)
+		return NULL;
+
+	if ((data->state_count < 2) ||
+	    (data->pct_status.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+	    (data->pct_control.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+	    (data->pct_status.address != MSR_IA32_PERF_STATUS) ||
+	    (data->pct_control.address != MSR_IA32_PERF_CTL))
+		goto out;
+
+	table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->state_count + 1), GFP_KERNEL);
+	if (!table)
+		goto out;
+
+	for (i=0; i < data->state_count; i++) {
+		table[i].index = data->states[i].control;
+		table[i].frequency = data->states[i].core_frequency * 1000;
+	}
+        table[data->state_count].frequency = CPUFREQ_TABLE_END;
+
+ out:
+	acpi_processor_perflib_unregister(&perflib_driver, 0);
+	return table;
+
+}
+#endif
+
 
 /**
  * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
@@ -348,15 +406,19 @@
 	for(model = models; model->model_name != NULL; model++)
 		if (strcmp(cpu->x86_model_id, model->model_name) == 0)
 			break;
-	if (model->model_name == NULL) {
-		printk(KERN_INFO PFX "no support for CPU model \"%s\": "
+	if (model->model_name) {
+		centrino_table = model->op_points;
+	} else if (model->model_name == NULL) {
+		printk(KERN_INFO PFX "no hardcoded support for CPU model \"%s\": "
 		       "send /proc/cpuinfo to " MAINTAINER "\n",
 		       cpu->x86_model_id);
-		return -ENOENT;
+#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
+		centrino_table = get_frequency_table_from_acpi();
+		if (!centrino_table)
+#endif
+			return -ENOENT;
 	}
 
-	centrino_model = model;
-		
 	printk(KERN_INFO PFX "found \"%s\": max frequency: %dkHz\n",
 	       model->model_name, model->max_freq);

WARNING: multiple messages have this Message-ID (diff)
From: Dominik Brodowski <linux-JhLEnvuH02M@public.gmane.org>
To: David Moore <dcm-HInyCGIudOg@public.gmane.org>
Cc: Jeremy Fitzhardinge <jeremy-TSDbQ3PG+2Y@public.gmane.org>,
	Ducrot Bruno <ducrot-kk6yZipjEM5g9hUCZPvPmw@public.gmane.org>,
	Andrew Grover
	<andrew.grover-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	cpufreq list <cpufreq-1walMZg8u8rXmaaqVzeoHQ@public.gmane.org>,
	"Adachi,
	Kenichi"
	<adachi-fvZ7ij+YLgEZc9YY0SgeQc8NsWr+9BEh@public.gmane.org>,
	acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: [RFC] cpufreq: use new acpi processor perflib in speedstep-centrino [Was: Re: [ACPI] _PDC method in DSDT]
Date: Fri, 5 Sep 2003 01:19:32 +0200	[thread overview]
Message-ID: <20030904231932.GA8518@brodo.de> (raw)
In-Reply-To: <1056491271.3979.15.camel-cfibRQahR+cF6I9xFAAkN5QCsf4PZ8us@public.gmane.org>

This patch modifies the speedstep-centrino driver to use the ACPI 
processor perflib if no hardcoded value could be found. Centrino-specific
stuff is taken from a patch to arch/i386/kernel/cpu/cpufreq/acpi.c by 
David Moore [in this thread].

 arch/i386/kernel/cpu/cpufreq/Kconfig              |   14 +++
 arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c |   88 ++++++++++++++++++----
2 files changed, 89 insertions(+), 13 deletions(-)

diff -ruN linux-original/arch/i386/kernel/cpu/cpufreq/Kconfig linux/arch/i386/kernel/cpu/cpufreq/Kconfig
--- linux-original/arch/i386/kernel/cpu/cpufreq/Kconfig	2003-09-04 21:36:58.000000000 +0200
+++ linux/arch/i386/kernel/cpu/cpufreq/Kconfig	2003-09-05 01:13:44.374639488 +0200
@@ -113,6 +113,20 @@
 	  
 	  If in doubt, say N.
 
+config X86_SPEEDSTEP_CENTRINO_ACPI
+	bool "Fall back to ACPI tables info"
+	depends on X86_SPEEDSTEP_CENTRINO && ACPI_PROCESSOR_PERFLIB
+	default n
+	help
+	  If your Intel Pentium M (Centrino) CPU is so new that
+	  it cannot be found yet by the Intel Enhanced SpeedStep
+	  CPUfreq driver, you might want to try enabling this option.
+
+	  It reads out the ACPI tables trying to determine the correct
+	  settings.
+	  
+	  If in doubt, say N.
+
 config X86_SPEEDSTEP_LIB
        tristate
        depends on X86_SPEEDSTEP_ICH
diff -ruN linux-original/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
--- linux-original/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2003-09-04 20:52:48.000000000 +0200
+++ linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2003-09-05 01:13:55.006023272 +0200
@@ -37,6 +37,7 @@
 #define dprintk(msg...) do { } while(0)
 #endif
 
+
 struct cpu_model
 {
 	const char	*model_name;
@@ -46,7 +47,7 @@
 };
 
 /* Operating points for current CPU */
-static const struct cpu_model *centrino_model;
+static struct cpufreq_frequency_table *centrino_table;
 
 /* Computes the correct form for IA32_PERF_CTL MSR for a particular
    frequency/voltage operating point; frequency in MHz, volts in mV.
@@ -196,7 +197,7 @@
 {
 	unsigned freq;
 
-	if (policy->cpu != 0 || centrino_model == NULL)
+	if (policy->cpu != 0 || centrino_table == NULL)
 		return -ENODEV;
 
 	freq = get_cur_freq();
@@ -207,8 +208,8 @@
 
 	dprintk(KERN_INFO PFX "centrino_cpu_init: policy=%d cur=%dkHz\n",
 		policy->policy, policy->cur);
-	
-	return cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
+
+	return cpufreq_frequency_table_cpuinfo(policy, centrino_table);
 }
 
 /**
@@ -220,7 +221,7 @@
  */
 static int centrino_verify (struct cpufreq_policy *policy)
 {
-	return cpufreq_frequency_table_verify(policy, centrino_model->op_points);
+	return cpufreq_frequency_table_verify(policy, centrino_table);
 }
 
 /**
@@ -237,14 +238,14 @@
 	unsigned int	msr, oldmsr, h;
 	struct cpufreq_freqs	freqs;
 
-	if (centrino_model == NULL)
+	if (centrino_table == NULL)
 		return -ENODEV;
 
-	if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
+	if (cpufreq_frequency_table_target(policy, centrino_table, target_freq,
 					   relation, &newstate))
 		return -EINVAL;
 
-	msr = centrino_model->op_points[newstate].index;
+	msr = centrino_table[newstate].index;
 	rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
 
 	if (msr == (oldmsr & 0xffff))
@@ -293,6 +294,63 @@
 	.owner		= THIS_MODULE,
 };
 
+#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+
+#define ACPI_PDC_REVISION_ID			0x1
+#define ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP	0x1
+
+static struct cpufreq_frequency_table * get_frequency_table_from_acpi(void) 
+{
+	union acpi_object		arg0 = {ACPI_TYPE_BUFFER};
+	u32				arg0_buf[3];
+	struct acpi_object_list		arg_list = {1, &arg0};
+	struct acpi_perflib_driver	perflib_driver;
+	struct acpi_perflib_data 	*data;
+	struct cpufreq_frequency_table	*table = NULL;
+	int				i;
+
+	/* First call _PDC, if available, to indicate to ACPI that this
+	 * driver supports Enhanced Speedstep.
+	 * Documentation for the _PDC method is at:
+	 * http://www.microsoft.com/whdc/hwdev/tech/onnow/procperfctrl.mspx */
+	arg0.buffer.length = 12;
+	arg0.buffer.pointer = (u8 *) arg0_buf;
+	arg0_buf[0] = ACPI_PDC_REVISION_ID;
+	arg0_buf[1] = 1;
+	arg0_buf[2] = ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP;
+
+	perflib_driver.pdc = &arg_list;
+
+	data = acpi_processor_perflib_register(&perflib_driver, 0);
+	if (!data)
+		return NULL;
+
+	if ((data->state_count < 2) ||
+	    (data->pct_status.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+	    (data->pct_control.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+	    (data->pct_status.address != MSR_IA32_PERF_STATUS) ||
+	    (data->pct_control.address != MSR_IA32_PERF_CTL))
+		goto out;
+
+	table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->state_count + 1), GFP_KERNEL);
+	if (!table)
+		goto out;
+
+	for (i=0; i < data->state_count; i++) {
+		table[i].index = data->states[i].control;
+		table[i].frequency = data->states[i].core_frequency * 1000;
+	}
+        table[data->state_count].frequency = CPUFREQ_TABLE_END;
+
+ out:
+	acpi_processor_perflib_unregister(&perflib_driver, 0);
+	return table;
+
+}
+#endif
+
 
 /**
  * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
@@ -348,15 +406,19 @@
 	for(model = models; model->model_name != NULL; model++)
 		if (strcmp(cpu->x86_model_id, model->model_name) == 0)
 			break;
-	if (model->model_name == NULL) {
-		printk(KERN_INFO PFX "no support for CPU model \"%s\": "
+	if (model->model_name) {
+		centrino_table = model->op_points;
+	} else if (model->model_name == NULL) {
+		printk(KERN_INFO PFX "no hardcoded support for CPU model \"%s\": "
 		       "send /proc/cpuinfo to " MAINTAINER "\n",
 		       cpu->x86_model_id);
-		return -ENOENT;
+#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
+		centrino_table = get_frequency_table_from_acpi();
+		if (!centrino_table)
+#endif
+			return -ENOENT;
 	}
 
-	centrino_model = model;
-		
 	printk(KERN_INFO PFX "found \"%s\": max frequency: %dkHz\n",
 	       model->model_name, model->max_freq);

  parent reply	other threads:[~2003-09-04 23:19 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-23  9:19 [ACPI] _PDC method in DSDT Grover, Andrew
2003-06-23  9:19 ` Grover, Andrew
2003-06-23 13:38 ` Dominik Brodowski
2003-06-23 13:38   ` Dominik Brodowski
2003-06-23 16:11   ` Ducrot Bruno
2003-06-23 16:11     ` Ducrot Bruno
2003-06-23 17:12     ` Jeremy Fitzhardinge
2003-06-23 17:12       ` Jeremy Fitzhardinge
2003-06-23 20:02       ` David Moore
2003-06-23 20:02         ` David Moore
2003-06-23 21:37         ` Dominik Brodowski
2003-06-23 21:37           ` Dominik Brodowski
2003-06-24  1:14           ` David Moore
2003-06-24  1:14             ` David Moore
2003-06-24  1:37             ` Jeremy Fitzhardinge
2003-06-24  1:37               ` Jeremy Fitzhardinge
2003-06-24  2:02               ` David Moore
2003-06-24  2:02                 ` David Moore
2003-06-24  2:16                 ` Jeremy Fitzhardinge
2003-06-24  2:16                   ` Jeremy Fitzhardinge
2003-06-24  9:18                 ` Ducrot Bruno
2003-06-24  9:18                   ` Ducrot Bruno
2003-06-24 21:47                   ` David Moore
2003-06-24 21:47                     ` David Moore
2003-06-26 10:40                     ` Ducrot Bruno
2003-06-26 10:40                       ` Ducrot Bruno
2003-06-26 11:13                       ` Ducrot Bruno
2003-06-26 11:13                         ` Ducrot Bruno
2003-09-04 23:19                     ` Dominik Brodowski [this message]
2003-09-04 23:19                       ` [RFC] cpufreq: use new acpi processor perflib in speedstep-centrino [Was: Re: [ACPI] _PDC method in DSDT] Dominik Brodowski
2003-09-05 16:53                       ` Jeremy Fitzhardinge
2003-09-05 16:53                         ` Jeremy Fitzhardinge

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030904231932.GA8518@brodo.de \
    --to=linux@brodo.de \
    --cc=acpi-devel@lists.sourceforge.net \
    --cc=adachi@rd.scei.sony.co.jp \
    --cc=andrew.grover@intel.com \
    --cc=cpufreq@www.linux.org.uk \
    --cc=dcm@acm.org \
    --cc=ducrot@poupinou.org \
    --cc=jeremy@goop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.