cpufreq Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Bruno Ducrot <ducrot@poupinou.org>
To: Alexey Starikovskiy <alexey_y_starikovskiy@linux.intel.com>
Cc: cpufreq@lists.linux.org.uk, Dave Jones <davej@redhat.com>
Subject: Re: [PATCH 3/8] acpi-cpufreq: merge acpi functionality of cpufreq drivers
Date: Wed, 2 Aug 2006 11:27:33 +0200	[thread overview]
Message-ID: <20060802092733.GI17014@poupinou.org> (raw)
In-Reply-To: <44CE4F8A.5060600@linux.intel.com>

I've not checked carrefully but it seems to me you are breaking
powernow-k8.

On Mon, Jul 31, 2006 at 10:44:26PM +0400, Alexey Starikovskiy wrote:
> acpi-cpufreq.c |  157 
> +++++++++++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 141 insertions(+), 16 deletions(-)
> 
> merge acpi functionality of cpufreq drivers
> 
> Signed-off: Denis Sadykov <denis.m.sadykov@intel.com>
> Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
> Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy at intel.com>
> 
> Index: linux-2.6.17/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
> ===================================================================
> --- linux-2.6.17.orig/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 
> 2006-07-13 17:52:15.000000000 +0000
> +++ linux-2.6.17/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2006-07-13 
> 18:15:30.000000000 +0000
> @@ -49,9 +49,16 @@
> MODULE_DESCRIPTION("ACPI Processor P-States Driver");
> MODULE_LICENSE("GPL");
> 
> +enum {
> +	UNDEFINED_CAPABLE = 0,
> +	SYSTEM_MSR_CAPABLE,
> +	SYSTEM_IO_CAPABLE,
> +};
> +
> struct acpi_cpufreq_data {
> 	struct acpi_processor_performance	*acpi_data;
> 	struct cpufreq_frequency_table		*freq_table;
> +	unsigned int				cpu_fet;
> };
> 
> static struct acpi_cpufreq_data			*drv_data[NR_CPUS];
> @@ -59,7 +66,29 @@
> 
> static struct cpufreq_driver			acpi_cpufreq_driver;
> 
> -static unsigned extract_freq(u32 value, struct acpi_cpufreq_data *data)
> +static int check_speedstep_cpu(unsigned int cpuid)
> +{
> +	struct cpuinfo_x86 *cpu = &cpu_data[cpuid];
> +
> +	if (cpu->x86_vendor != X86_VENDOR_INTEL ||
> +				!cpu_has(cpu, X86_FEATURE_EST))
> +		return (0);
> +	return (1);
> +}
> +
> +static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
> +{
> +	int i;
> +
> +	msr &= 0xffff;
> +	for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) 
> {
> +		if (msr == data->freq_table[i].index)
> +			return data->freq_table[i].frequency;
> +	}
> +	return (0);
> +}
> +
> +static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
> {
> 	struct acpi_processor_performance	*perf;
> 	int					i;
> @@ -74,6 +103,18 @@
> 	return (0);
> }
> 
> +static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data)
> +{
> +	switch (data->cpu_fet) {
> +	case SYSTEM_MSR_CAPABLE:
> +		return extract_msr(val, data);
> +	case SYSTEM_IO_CAPABLE:
> +		return extract_io(val, data);
> +	default:
> +		return (0);
> +	}
> +}
> +
> static void wrport(u16 port, u8 bit_width, u32 value)
> {
> 	if (bit_width <= 8) {
> @@ -97,33 +138,59 @@
> 	return (0);
> }
> 
> +struct msr_addr {
> +	u32	reg;
> +};
> +
> struct io_addr {
> 	u16	port;
> 	u8	bit_width;
> };
> 
> +typedef union {
> +	struct msr_addr		msr;
> +	struct io_addr		io;
> +} drv_addr_union;
> +
> struct drv_cmd {
> +	unsigned int	type;
> 	cpumask_t	mask;
> -	struct io_addr	addr;
> +	drv_addr_union	addr;
> 	u32		val;
> };
> 
> static void do_drv_read(void *cmd_block)
> {
> 	struct drv_cmd	*cmd = (struct drv_cmd *)cmd_block;
> +	u32		h;
> 
> -	cmd->val = rdport(cmd->addr.port, cmd->addr.bit_width);
> -
> -	return;
> +	switch (cmd->type) {
> +	case SYSTEM_MSR_CAPABLE:
> +		rdmsr(cmd->addr.msr.reg, cmd->val, h);
> +		return;
> +	case SYSTEM_IO_CAPABLE:
> +		cmd->val = rdport(cmd->addr.io.port, cmd->addr.io.bit_width);
> +		return;
> +	default:
> +		return;
> +	}
> }
> 
> static void do_drv_write(void *cmd_block)
> {
> 	struct drv_cmd	*cmd = (struct drv_cmd *)cmd_block;
> +	u32		h = 0;
> 
> -	wrport(cmd->addr.port, cmd->addr.bit_width, cmd->val);
> -
> -	return;
> +	switch (cmd->type) {
> +	case SYSTEM_MSR_CAPABLE:
> +		wrmsr(cmd->addr.msr.reg, cmd->val, h);
> +		return;
> +	case SYSTEM_IO_CAPABLE:
> +		wrport(cmd->addr.io.port, cmd->addr.io.bit_width, cmd->val);
> +		return;
> +	default:
> +		return;
> +	}
> }
> 
> static inline void drv_read(struct drv_cmd *cmd)
> @@ -162,9 +229,20 @@
> 		return (0);
> 	}
> 
> -	perf = drv_data[first_cpu(mask)]->acpi_data;
> -	cmd.addr.port = perf->control_register.address;
> -	cmd.addr.bit_width = perf->control_register.bit_width;
> +	switch (drv_data[first_cpu(mask)]->cpu_fet) {
> +	case SYSTEM_MSR_CAPABLE:
> +		cmd.type = SYSTEM_MSR_CAPABLE;
> +		cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
> +		break;
> +	case SYSTEM_IO_CAPABLE:
> +		cmd.type = SYSTEM_IO_CAPABLE;
> +		perf = drv_data[first_cpu(mask)]->acpi_data;
> +		cmd.addr.io.port = perf->control_register.address;
> +		cmd.addr.io.bit_width = perf->control_register.bit_width;
> +		break;
> +	default:
> +		return (0);
> +	}
> 	cmd.mask = mask;
> 
> 	drv_read(&cmd);
> @@ -205,6 +283,7 @@
> 	struct cpufreq_freqs			freqs;
> 	cpumask_t				online_policy_cpus;
> 	struct drv_cmd				cmd;
> +	u32					msr;
> 	unsigned int				next_state = 0;
> 	unsigned int				i;
> 	int					result = 0;
> @@ -235,10 +314,22 @@
> 	cmd.val = get_cur_val(online_policy_cpus);
> 	freqs.old = extract_freq(cmd.val, data);
> 
> -	cmd.addr.port = perf->control_register.address;
> -	cmd.addr.bit_width = perf->control_register.bit_width;
> -	cmd.val = (u32) perf->states[next_state].control;
> -	freqs.new = data->freq_table[next_state].frequency;
> +	if (data->cpu_fet == SYSTEM_MSR_CAPABLE) {
> +		cmd.type = SYSTEM_MSR_CAPABLE;
> +		cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
> +		msr = data->freq_table[next_state].index & 0xffff;
> +		cmd.val = (cmd.val & ~0xffff) | msr;
> +		freqs.new = extract_msr(msr, data);
> +	} else if (data->cpu_fet == SYSTEM_IO_CAPABLE) {
> +		cmd.type = SYSTEM_IO_CAPABLE;
> +		cmd.addr.io.port = perf->control_register.address;
> +		cmd.addr.io.bit_width = perf->control_register.bit_width;
> +		cmd.val = (u32) perf->states[next_state].control;
> +		freqs.new = data->freq_table[next_state].frequency;
> +	} else {
> +		return -ENODEV;
> +	}
> +
> 
> 	if (freqs.new == freqs.old) {
> 		return (0);
> @@ -336,6 +427,15 @@
> 	switch (perf->control_register.space_id) {
> 		case ACPI_ADR_SPACE_SYSTEM_IO:
> 			dprintk("SYSTEM IO addr space\n");
> +			data->cpu_fet = SYSTEM_IO_CAPABLE;
> +			break;
> +		case ACPI_ADR_SPACE_FIXED_HARDWARE:
> +			dprintk("HARDWARE addr space\n");
> +			if (!check_speedstep_cpu(cpu)) {
> +				result = -ENODEV;
> +				goto err_unreg;
> +			}
> +			data->cpu_fet = SYSTEM_MSR_CAPABLE;
> 			break;
> 		default:
> 			dprintk("unknown addr space\n");
> @@ -351,7 +451,11 @@
> 	}
> 
> 	for (i = 0; i < perf->state_count; i++) {
> -		data->freq_table[i].index = i;
> +		if (data->cpu_fet == SYSTEM_MSR_CAPABLE) {
> +			data->freq_table[i].index = perf->states[i].control;
> +		} else {
> +			data->freq_table[i].index = i;
> +		}
> 		data->freq_table[i].frequency =
> 			perf->states[i].core_frequency * 1000;
> 	}
> @@ -371,6 +475,7 @@
> 	unsigned int			cpu = policy->cpu;
> 	struct cpuinfo_x86		*c = &cpu_data[policy->cpu];
> 	struct acpi_cpufreq_data	*data;
> +	struct drv_cmd			cmd;
> 	unsigned int			result = 0;
> 	unsigned int			i;
> 
> @@ -393,6 +498,26 @@
> 		goto err_free;
> 	}
> 
> +	if (data->cpu_fet == SYSTEM_MSR_CAPABLE) {
> +	/* Check to see if Enhanced SpeedStep is enabled, and try to
> +	   enable it if not. */
> +		cmd.mask = cpumask_of_cpu(cpu);
> +		cmd.type = SYSTEM_MSR_CAPABLE;
> +		cmd.addr.msr.reg = MSR_IA32_MISC_ENABLE;
> +		drv_read(&cmd);
> +
> +		if (!(cmd.val & (1 << 16))) {
> +			cmd.val |= (1 << 16);
> +			drv_write(&cmd);
> +			/* check to see if it stuck */
> +			drv_read(&cmd);
> +			if (!(cmd.val & ( 1<< 16))) {
> +				result = -ENODEV;
> +				goto err_free;
> +			}
> +		}
> +	}
> +
> 	policy->cpus = data->acpi_data->shared_cpu_map;
> 	for_each_cpu_mask(i, policy->cpus) {
> 		drv_data[i] = data;
> 
> _______________________________________________
> Cpufreq mailing list
> Cpufreq@lists.linux.org.uk
> http://lists.linux.org.uk/mailman/listinfo/cpufreq

-- 
Bruno Ducrot

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

  reply	other threads:[~2006-08-02  9:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-31 18:44 [PATCH 3/8] acpi-cpufreq: merge acpi functionality of cpufreq drivers Alexey Starikovskiy
2006-08-02  9:27 ` Bruno Ducrot [this message]
2006-08-02 18:44   ` Alexey Starikovskiy
2006-08-03 16:11     ` Bruno Ducrot
2006-08-03 16:20       ` Dave Jones
2006-08-03 17:05         ` Alexey Starikovskiy
2006-08-04  9:22         ` Bruno Ducrot
2006-08-04 17:03           ` Dave Jones
2006-08-07  8:48             ` Bruno Ducrot
2006-08-07 16:55               ` Dave Jones
2006-08-03 16:28       ` Alexey Starikovskiy

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=20060802092733.GI17014@poupinou.org \
    --to=ducrot@poupinou.org \
    --cc=alexey_y_starikovskiy@linux.intel.com \
    --cc=cpufreq@lists.linux.org.uk \
    --cc=davej@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox