Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Assistance Kernel & Hardware
  • Search

user undervolting

Kernel not recognizing your hardware? Problems with power management or PCMCIA? What hardware is compatible with Gentoo? See here. (Only for kernels supported by Gentoo.)
Post Reply
Advanced search
340 posts
  • Page 3 of 14
    • Jump to page:
  • Previous
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 14
  • Next
Author
Message
Grooby
n00b
n00b
Posts: 47
Joined: Wed Jun 08, 2005 3:59 am
Contact:
Contact Grooby
Website

benchmarks?

  • Quote

Post by Grooby » Mon Aug 29, 2005 8:54 pm

just out of curiousity, has anyone done any battery benchmark? how much extra time do you get out of these undervolted CPUs?
Top
knefas
l33t
l33t
User avatar
Posts: 828
Joined: Sun Dec 21, 2003 1:20 am

  • Quote

Post by knefas » Mon Aug 29, 2005 9:13 pm

rschwarze wrote:i don't know what the four voltage numbers mean.
btw, which temperature do you get in idle mode? and which temperature while compiling?
I get 55C idle, and 60/61C compiling (1600 @ 0.908 volt). Before @ 1600 I got over 76, so this is very very good.
I've added a dummy mode (200) and cpufreq-info is showing it.
The only thing (one of the many things, actually! ;) ) I don't understand is why on Windows I can go 800 @ 0.700 Volt and here in Linux a have to run at least 0.750 Volt. On Win I can stay 49C idle, here I can't go lower than 54. That's quite a mistery!
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Mon Aug 29, 2005 10:23 pm

someone in this thread says, that he can do lower voltage when he use 600 mhz. this is a bit strange, because i don't think that the processor really use the 600 mhz. but maybe it is worse a try.

my idle temperature is about 48-50°C.

during long compilation my temperature goes up to 60 degrees, but then the cooler cooles it down to 50 degrees again.

@grooby: for me the battery time in idle mode is 4h without and 4.5h with undervolting. but thats not so important for me. without undervolting my cooler runs nearly all the time and the notebook is very hot (which isn't good for the battery, for example). with the undervolting, the cooler runs only during compilation and not all the time but 40% i think.
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Tue Sep 06, 2005 4:48 pm

Hi,

I didn't manage to get it working for me, can you help me? I'm running Suse 9.3 (Kernel 2.6.11.4-21.9), but I think that won't make any difference, am I right?

My System is a Samsung X20 1600V, powered by an Intel Centrino 1,60Ghz Prozessor (Modelnumber 730, codename sonoma)

Perhaps anyone who has the same processor can post his complete speedstep-centrino.c?

Thank you!

And is there any programm that can read the vcore actually used by the kernel?

I think I followed all hints posted in this thread, but it didn't seem to work. cpufreq-info still says

cpufrequtils 0.2: cpufreq-info (C) Dominik Brodowski 2004
Bitte melden Sie Fehler an linux@brodo.de.
analysiere CPU 0:
Treiber: acpi-cpufreq
Folgende CPUs können nur gleichzeitig ihre Frequenz variieren: 0
Hardwarebedingte Grenzen der Taktfrequenz: 800 MHz - 1.60 GHz
mögliche Taktfrequenzen: 1.60 GHz, 1.33 GHz, 1.07 GHz, 800 MHz
mögliche Regler: userspace, performance
momentane Taktik: die Frequenz soll innerhalb 800 MHz und 1.60 GHz.
liegen. Der Regler "userspace" kann frei entscheiden,
welche Taktfrequenz innerhalb dieser Grenze verwendet wird.
momentane Taktfrequenz ist 800 MHz.


My config files:

.config

#
# CPUFreq processor drivers
#
CONFIG_X86_ACPI_CPUFREQ=m
# CONFIG_X86_POWERNOW_K6 is not set
# CONFIG_X86_POWERNOW_K7 is not set
# CONFIG_X86_POWERNOW_K8 is not set
# CONFIG_X86_GX_SUSPMOD is not set
CONFIG_X86_SPEEDSTEP_CENTRINO=m
# CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI is not set
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
# CONFIG_X86_SPEEDSTEP_ICH is not set
# CONFIG_X86_SPEEDSTEP_SMI is not set
# CONFIG_X86_P4_CLOCKMOD is not set
# CONFIG_X86_CPUFREQ_NFORCE2 is not set
# CONFIG_X86_LONGRUN is not set
# CONFIG_X86_LONGHAUL is not set

#
# shared options
#
CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y

#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=m
# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
CONFIG_PCI_MSI=y
# CONFIG_PCI_LEGACY_PROC is not set
# CONFIG_PCI_NAMES is not set
CONFIG_ISA=y
# CONFIG_EISA is not set
# CONFIG_MCA is not set
CONFIG_SCx200=m

speedstep-centrino.c

/*
* cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium
* M (part of the Centrino chipset).
*
* Despite the "SpeedStep" in the name, this is almost entirely unlike
* traditional SpeedStep.
*
* Modelled on speedstep.c
*
* Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
*
* WARNING WARNING WARNING
*
* This driver manipulates the PERF_CTL MSR, which is only somewhat
* documented. While it seems to work on my laptop, it has not been
* tested anywhere else, and it may not work for you, do strange
* things or simply crash.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/compiler.h>

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif

#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>

#include "speedstep-est-common.h"

#define PFX "speedstep-centrino: "
#define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>"

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)


struct cpu_id
{
__u8 x86; /* CPU family */
__u8 x86_model; /* model */
__u8 x86_mask; /* stepping */
};

enum {
CPU_BANIAS,
CPU_DOTHAN_A1,
CPU_DOTHAN_A2,
CPU_DOTHAN_B0,
CPU_DOTHAN_C0,
};

static const struct cpu_id cpu_ids[] = {
[CPU_BANIAS] = { 6, 9, 5 },
[CPU_DOTHAN_A1] = { 6, 13, 1 },
[CPU_DOTHAN_A2] = { 6, 13, 2 },
[CPU_DOTHAN_B0] = { 6, 13, 6 },
[CPU_DOTHAN_C0] = { 6, 13, 8 },
};
#define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0]))

struct cpu_model
{
const struct cpu_id *cpu_id;
const char *model_name;
unsigned max_freq; /* max clock in kHz */

struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
};
static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);

/* Operating points for current CPU */
static struct cpu_model *centrino_model[NR_CPUS];
static const struct cpu_id *centrino_cpu[NR_CPUS];

static struct cpufreq_driver centrino_driver;

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE

/* Computes the correct form for IA32_PERF_CTL MSR for a particular
frequency/voltage operating point; frequency in MHz, volts in mV.
This is stored as "index" in the structure. */
#define OP(mhz, mv) \
{ \
.frequency = (mhz) * 1000, \
.index = (((mhz)/100) << 8) | ((mv - 700) / 16) \
}

/*
* These voltage tables were derived from the Intel Pentium M
* datasheet, document 25261202.pdf, Table 5. I have verified they
* are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
* M.
*/

/* Ultra Low Voltage Intel Pentium M processor 900MHz (Banias) */
static struct cpufreq_frequency_table banias_900[] =
{
OP(600, 844),
OP(800, 988),
OP(900, 1004),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Ultra Low Voltage Intel Pentium M processor 1000MHz (Banias) */
static struct cpufreq_frequency_table banias_1000[] =
{
OP(600, 844),
OP(800, 972),
OP(900, 988),
OP(1000, 1004),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Low Voltage Intel Pentium M processor 1.10GHz (Banias) */
static struct cpufreq_frequency_table banias_1100[] =
{
OP( 600, 956),
OP( 800, 1020),
OP( 900, 1100),
OP(1000, 1164),
OP(1100, 1180),
{ .frequency = CPUFREQ_TABLE_END }
};


/* Low Voltage Intel Pentium M processor 1.20GHz (Banias) */
static struct cpufreq_frequency_table banias_1200[] =
{
OP( 600, 956),
OP( 800, 1004),
OP( 900, 1020),
OP(1000, 1100),
OP(1100, 1164),
OP(1200, 1180),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.30GHz (Banias) */
static struct cpufreq_frequency_table banias_1300[] =
{
OP( 600, 956),
OP( 800, 1260),
OP(1000, 1292),
OP(1200, 1356),
OP(1300, 1388),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.40GHz (Banias) */
static struct cpufreq_frequency_table banias_1400[] =
{
OP( 600, 956),
OP( 800, 1180),
OP(1000, 1308),
OP(1200, 1436),
OP(1400, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.50GHz (Banias) */
static struct cpufreq_frequency_table banias_1500[] =
{
OP( 600, 956),
OP( 800, 1116),
OP(1000, 1228),
OP(1200, 1356),
OP(1400, 1452),
OP(1500, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.60GHz (Banias) */
static struct cpufreq_frequency_table banias_1600[] =
{
OP( 600, 956),
OP( 800, 1036),
OP(1000, 1164),
OP(1200, 1276),
OP(1400, 1420),
OP(1600, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.70GHz (Banias) */
static struct cpufreq_frequency_table banias_1700[] =
{
OP( 600, 956),
OP( 800, 1004),
OP(1000, 1116),
OP(1200, 1228),
OP(1400, 1308),
OP(1700, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};
#undef OP

/* Dothan processor datasheet 30218903.pdf defines 4 voltages for each
frequency (VID#A through VID#D) - this macro allows us to define all
of these but we only use the VID#C voltages at compile time - this may
need some work if we want to select the voltage profile at runtime. */

#define OP(mhz, mva, mvb, mvc, mvd) \
{ \
.frequency = (mhz) * 1000, \
.index = (((mhz)/100) << 8) | ((mvc - 700) / 16) \
}

/* Intel Pentium M processor 733 / 1.10GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1100[] =
{
OP( 500, 700, 700, 700, 700),
OP( 600, 700, 700, 700, 700),
OP( 800, 748, 748, 748, 748),
OP( 900, 764, 764, 764, 764),
OP(1000, 812, 812, 812, 812),
OP(1100, 844, 844, 844, 844),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 710 / 1.40GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1400[] =
{

OP( 400, 700, 700, 700, 700),
OP( 600, 700, 700, 700, 700),
OP( 800, 750, 750, 750, 750),
OP(1000, 810, 810, 810, 810),
OP(1200, 870, 870, 870, 870),
OP(1400, 920, 920, 920, 920),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 715 / 1.50GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1500[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1068, 1068, 1068, 1052),
OP(1000, 1148, 1148, 1132, 1116),
OP(1200, 1228, 1212, 1212, 1180),
OP(1500, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 725 / 1.60GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1600[] =
{
OP( 600, 800, 988, 988, 988),
OP( 800, 800, 1068, 1052, 1052),
OP(1000, 1132, 1132, 1116, 1116),
OP(1200, 1212, 1196, 1180, 1164),
OP(1400, 1276, 1260, 1244, 1228),
OP(1600, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 735 / 1.70GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1700[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1052, 1052, 1052, 1052),
OP(1000, 1116, 1116, 1116, 1100),
OP(1200, 1180, 1180, 1164, 1148),
OP(1400, 1244, 1244, 1228, 1212),
OP(1700, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 745 / 1.80GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1800[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1052, 1052, 1052, 1036),
OP(1000, 1116, 1100, 1100, 1084),
OP(1200, 1164, 1164, 1148, 1132),
OP(1400, 1228, 1212, 1212, 1180),
OP(1600, 1292, 1276, 1260, 1228),
OP(1800, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 755 / 2.00GHz (Dothan) */
static struct cpufreq_frequency_table dothan_2000[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1052, 1036, 1036, 1036),
OP(1000, 1100, 1084, 1084, 1084),
OP(1200, 1148, 1132, 1132, 1116),
OP(1400, 1196, 1180, 1180, 1164),
OP(1600, 1244, 1228, 1228, 1196),
OP(1800, 1292, 1276, 1276, 1244),
OP(2000, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 750 / 1.86GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1867[] =
{
OP( 800, 880, 880, 880, 880),
OP(1333, 1010, 1010, 1010, 1010),
OP(1867, 1120, 1120, 1120, 1120),
{ .frequency = CPUFREQ_TABLE_END }
};

#undef OP

#define _BANIAS(cpuid, max, name) \
{ .cpu_id = cpuid, \
.model_name = "Intel(R) Pentium(R) M processor " name "MHz", \
.max_freq = (max)*1000, \
.op_points = banias_##max, \
}
#define BANIAS(max) _BANIAS(&cpu_ids[CPU_BANIAS], max, #max)

#define DOTHAN(cpuid, max, name) \
{ .cpu_id = cpuid, \
.model_name = "Intel(R) Pentium(R) M processor " name "GHz", \
.max_freq = (max)*1000, \
.op_points = dothan_##max, \
}

/* CPU models, their operating frequency range, and freq/voltage
operating points */
static struct cpu_model models[] =
{
_BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"),
BANIAS(1000),
BANIAS(1100),
BANIAS(1200),
BANIAS(1300),
BANIAS(1400),
BANIAS(1500),
BANIAS(1600),
BANIAS(1700),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1100, "1.10"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1400, "1.40"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1500, "1.50"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1600, "1.60"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1700, "1.70"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1800, "1.80"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 2000, "2.00"),
DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1867, "1.86"),

/* NULL model_name is a wildcard */
{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
{ &cpu_ids[CPU_DOTHAN_C0], NULL, 0, NULL },

{ NULL, }
};
#undef _BANIAS
#undef BANIAS
#undef DOTHAN

static int centrino_cpu_init_table(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
struct cpu_model *model;

for(model = models; model->cpu_id != NULL; model++)
if (centrino_verify_cpu_id(cpu, model->cpu_id) &&
(model->model_name == NULL ||
strcmp(cpu->x86_model_id, model->model_name) == 0))
break;

if (model->cpu_id == NULL) {
/* No match at all */
dprintk(KERN_INFO PFX "no support for CPU model \"%s\": "
"send /proc/cpuinfo to " MAINTAINER "\n",
cpu->x86_model_id);
return -ENOENT;
}

if (model->op_points == NULL) {
/* Matched a non-match */
dprintk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
cpu->x86_model_id);
#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
#endif
return -ENOENT;
}

centrino_model[policy->cpu] = model;

dprintk("found \"%s\": max frequency: %dkHz\n",
model->model_name, model->max_freq);

return 0;
}

#else
static inline int centrino_cpu_init_table(struct cpufreq_policy *policy) { return -ENODEV; }
#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */

static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x)
{
if ((c->x86 == x->x86) &&
(c->x86_model == x->x86_model) &&
(c->x86_mask == x->x86_mask))
return 1;
return 0;
}

/* To be called only after centrino_model is initialized */
static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
{
int i;

/*
* Extract clock in kHz from PERF_CTL value
* for centrino, as some DSDTs are buggy.
* Ideally, this can be done using the acpi_data structure.
*/
if ((centrino_cpu[cpu] == &cpu_ids[CPU_BANIAS]) ||
(centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_A1]) ||
(centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_B0]) ||
(centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_C0])) {
msr = (msr >> 8) & 0xff;
return msr * 100000;
}

if ((!centrino_model[cpu]) || (!centrino_model[cpu]->op_points))
return 0;

msr &= 0xffff;
for (i=0;centrino_model[cpu]->op_points.frequency != CPUFREQ_TABLE_END; i++) {
if (msr == centrino_model[cpu]->op_points.index)
return centrino_model[cpu]->op_points.frequency;
}
if (failsafe)
return centrino_model[cpu]->op_points[i-1].frequency;
else
return 0;
}

/* Return the current CPU frequency in kHz */
static unsigned int get_cur_freq(unsigned int cpu)
{
unsigned l, h;
unsigned clock_freq;
cpumask_t saved_mask;

saved_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu)
return 0;

rdmsr(MSR_IA32_PERF_STATUS, l, h);
clock_freq = extract_clock(l, cpu, 0);

if (unlikely(clock_freq == 0)) {
/*
* On some CPUs, we can see transient MSR values (which are
* not present in _PSS), while CPU is doing some automatic
* P-state transition (like TM2). Get the last freq set
* in PERF_CTL.
*/
rdmsr(MSR_IA32_PERF_CTL, l, h);
clock_freq = extract_clock(l, cpu, 1);
}

set_cpus_allowed(current, saved_mask);
return clock_freq;
}


#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI

static struct acpi_processor_performance p;

/*
* centrino_cpu_init_acpi - register with ACPI P-States library
*
* Register with the ACPI P-States library (part of drivers/acpi/processor.c)
* in order to determine correct frequency and voltage pairings by reading
* the _PSS of the ACPI DSDT or SSDT tables.
*/
static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
{
union acpi_object arg0 = {ACPI_TYPE_BUFFER};
u32 arg0_buf[3];
struct acpi_object_list arg_list = {1, &arg0};
unsigned long cur_freq;
int result = 0, i;
unsigned int cpu = policy->cpu;

/* _PDC settings */
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_EST_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_MSR;

p.pdc = &arg_list;

/* register with ACPI core */
if (acpi_processor_register_performance(&p, cpu)) {
dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");
return -EIO;
}

/* verify the acpi_data */
if (p.state_count <= 1) {
dprintk("No P-States\n");
result = -ENODEV;
goto err_unreg;
}

if ((p.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
(p.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
dprintk("Invalid control/status registers (%x - %x)\n",
p.control_register.space_id, p.status_register.space_id);
result = -EIO;
goto err_unreg;
}

for (i=0; i<p.state_count; i++) {
if (p.states.control != p.states.status) {
dprintk("Different control (%x) and status values (%x)\n",
p.states.control, p.states.status);
result = -EINVAL;
goto err_unreg;
}

if (!p.states.core_frequency) {
dprintk("Zero core frequency for state %u\n", i);
result = -EINVAL;
goto err_unreg;
}

if (p.states.core_frequency > p.states[0].core_frequency) {
dprintk("P%u has larger frequency (%u) than P0 (%u), skipping\n", i,
p.states.core_frequency, p.states[0].core_frequency);
p.states[i].core_frequency = 0;
continue;
}
}

centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
if (!centrino_model[cpu]) {
result = -ENOMEM;
goto err_unreg;
}
memset(centrino_model[cpu], 0, sizeof(struct cpu_model));

centrino_model[cpu]->model_name=NULL;
centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000;
centrino_model[cpu]->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) *
(p.state_count + 1), GFP_KERNEL);
if (!centrino_model[cpu]->op_points) {
result = -ENOMEM;
goto err_kfree;
}

for (i=0; i<p.state_count; i++) {
centrino_model[cpu]->op_points[i].index = p.states[i].control;
centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000;
dprintk("adding state %i with frequency %u and control value %04x\n",
i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
}
centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;

cur_freq = get_cur_freq(cpu);

for (i=0; i<p.state_count; i++) {
if (!p.states[i].core_frequency) {
dprintk("skipping state %u\n", i);
centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
continue;
}

if (extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0) !=
(centrino_model[cpu]->op_points[i].frequency)) {
dprintk("Invalid encoded frequency (%u vs. %u)\n",
extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0),
centrino_model[cpu]->op_points[i].frequency);
result = -EINVAL;
goto err_kfree_all;
}

if (cur_freq == centrino_model[cpu]->op_points[i].frequency)
p.state = i;
}

/* notify BIOS that we exist */
acpi_processor_notify_smm(THIS_MODULE);

return 0;

err_kfree_all:
kfree(centrino_model[cpu]->op_points);
err_kfree:
kfree(centrino_model[cpu]);
err_unreg:
acpi_processor_unregister_performance(&p, cpu);
dprintk(KERN_INFO PFX "invalid ACPI data\n");
return (result);
}
#else
static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; }
#endif

static int centrino_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
unsigned freq;
unsigned l, h;
int ret;
int i;

/* Only Intel makes Enhanced Speedstep-capable CPUs */
if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST))
return -ENODEV;

for (i = 0; i < N_IDS; i++)
if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
break;

if (i != N_IDS)
centrino_cpu[policy->cpu] = &cpu_ids[i];

if (is_const_loops_cpu(policy->cpu)) {
centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
}

if (centrino_cpu_init_acpi(policy)) {
if (policy->cpu != 0)
return -ENODEV;

if (!centrino_cpu[policy->cpu]) {
dprintk(KERN_INFO PFX "found unsupported CPU with "
"Enhanced SpeedStep: send /proc/cpuinfo to "
MAINTAINER "\n");
return -ENODEV;
}

if (centrino_cpu_init_table(policy)) {
return -ENODEV;
}
}

/* Check to see if Enhanced SpeedStep is enabled, and try to
enable it if not. */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);

if (!(l & (1<<16))) {
l |= (1<<16);
dprintk("trying to enable Enhanced SpeedStep (%x)\n", l);
wrmsr(MSR_IA32_MISC_ENABLE, l, h);

/* check to see if it stuck */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
if (!(l & (1<<16))) {
printk(KERN_INFO PFX "couldn't enable Enhanced SpeedStep\n");
return -ENODEV;
}
}

freq = get_cur_freq(policy->cpu);

policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */
policy->cur = freq;

dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);

ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model[policy->cpu]->op_points);
if (ret)
return (ret);

cpufreq_frequency_table_get_attr(centrino_model[policy->cpu]->op_points, policy->cpu);

return 0;
}

static int centrino_cpu_exit(struct cpufreq_policy *policy)
{
unsigned int cpu = policy->cpu;

if (!centrino_model[cpu])
return -ENODEV;

cpufreq_frequency_table_put_attr(cpu);

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
if (!centrino_model[cpu]->model_name) {
dprintk("unregistering and freeing ACPI data\n");
acpi_processor_unregister_performance(&p, cpu);
kfree(centrino_model[cpu]->op_points);
kfree(centrino_model[cpu]);
}
#endif

centrino_model[cpu] = NULL;

return 0;
}

/**
* centrino_verify - verifies a new CPUFreq policy
* @policy: new policy
*
* Limit must be within this model's frequency range at least one
* border included.
*/
static int centrino_verify (struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, centrino_model[policy->cpu]->op_points);
}

/**
* centrino_setpolicy - set a new CPUFreq policy
* @policy: new policy
* @target_freq: the target frequency
* @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* Sets a new CPUFreq policy.
*/
static int centrino_target (struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate = 0;
unsigned int msr, oldmsr, h, cpu = policy->cpu;
struct cpufreq_freqs freqs;
cpumask_t saved_mask;
int retval;

if (centrino_model[cpu] == NULL)
return -ENODEV;

/*
* Support for SMP systems.
* Make sure we are running on the CPU that wants to change frequency
*/
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, policy->cpus);
if (!cpu_isset(smp_processor_id(), policy->cpus)) {
dprintk("couldn't limit to CPUs in this domain\n");
return(-EAGAIN);
}

if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq,
relation, &newstate)) {
retval = -EINVAL;
goto migrate_end;
}

msr = centrino_model[cpu]->op_points[newstate].index;
rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);

if (msr == (oldmsr & 0xffff)) {
retval = 0;
dprintk("no change needed - msr was and needs to be %x\n", oldmsr);
goto migrate_end;
}

freqs.cpu = cpu;
freqs.old = extract_clock(oldmsr, cpu, 0);
freqs.new = extract_clock(msr, cpu, 0);

dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
target_freq, freqs.old, freqs.new, msr);

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);

/* all but 16 LSB are "reserved", so treat them with
care */
oldmsr &= ~0xffff;
msr &= 0xffff;
oldmsr |= msr;

wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);

retval = 0;
migrate_end:
set_cpus_allowed(current, saved_mask);
return (retval);
}

static struct freq_attr* centrino_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};

static struct cpufreq_driver centrino_driver = {
.name = "centrino", /* should be speedstep-centrino,
but there's a 16 char limit */
.init = centrino_cpu_init,
.exit = centrino_cpu_exit,
.verify = centrino_verify,
.target = centrino_target,
.get = get_cur_freq,
.attr = centrino_attr,
.owner = THIS_MODULE,
};


/**
* centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
*
* Initializes the Enhanced SpeedStep support. Returns -ENODEV on
* unsupported devices, -ENOENT if there's no voltage table for this
* particular CPU model, -EINVAL on problems during initiatization,
* and zero on success.
*
* This is quite picky. Not only does the CPU have to advertise the
* "est" flag in the cpuid capability flags, we look for a specific
* CPU model and stepping, and we need to have the exact model name in
* our voltage tables. That is, be paranoid about not releasing
* someone's valuable magic smoke.
*/
static int __init centrino_init(void)
{
struct cpuinfo_x86 *cpu = cpu_data;

if (!cpu_has(cpu, X86_FEATURE_EST))
return -ENODEV;

return cpufreq_register_driver(&centrino_driver);
}

static void __exit centrino_exit(void)
{
cpufreq_unregister_driver(&centrino_driver);
}

MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>");
MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors.");
MODULE_LICENSE ("GPL");

late_initcall(centrino_init);
module_exit(centrino_exit);
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Tue Sep 06, 2005 6:06 pm

i'm not sure. but is it possible, that you try to compile speedstep-centrino as a module?

that will _NOT_ work! you have to compile it into the kernel!

if this isn't the error, please let me know.

greets,

roman
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Tue Sep 06, 2005 10:38 pm

Hi,

Sorry, but I'm a Linux nub, which line do I have to check with "y" for NOT compiling it as a module but directly into the kernel? There are several lines speaking of speedstep or centrino in the .config, but no one has the exact term "speedstep-centrino.c" in it.

By the way, I copied the CPUFREQ part from the .config file you have posted here, and some parts of the speedstep-centrino.c from other posts in this topic.
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Tue Sep 06, 2005 10:50 pm

okay. you dont have to edit the .confg file manually. you can use menuconfig for that. when you are at the directory with the kernel sourcecode, (the directory where you do "make && make modules install" to compile your kernel) just type "make menuconfig". then you get a menu where you can make your selektions.

In this menu you go to "power management options". then go to "cpu frequency scaling". at this place you want to select (and you should really select it, not just make it as a module): "<*> Intel Enhanced SpeedStep". then there is an other option below that, which telly you: " [ ] Use ACPI tables to decode valid frequency/voltage pairs" this one must be _not_ selected.

so, then go ahead, compile your kernel, change your bootmanager to the new kernel and all that stuff. if you have any questions, also about compiling the kernel and stuff, you can ask me. (but i'm not sure if i can help very much, because i'm relatively new to linux, too)

oh, and i think you should delete the entry for the 1.6 dothan, because the driver don't know which one to use.
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Wed Sep 07, 2005 9:17 am

Hello,

i recompiled the kernel using the hints you have given me, but it still doesn't work.
In the menuconfig I can decide which governor to use as standard, performance or userspace, which one shuold I use?

And which entry am I supposed to delete? There is only one entry for the 1600 dothan.

Greetings,
Matthias
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Wed Sep 07, 2005 12:10 pm

okay:

which governor you use is not important for this undervolting thing. i myself use the "<*> 'conservative' cpufreq governor".
if you want to have speedstepping, you should make "Default CPUFreq governor (userspace) --->".

okay, you have the 1.6 sonoma, right? so in the speedstep-centrino.c file there is also a table of frequencies for the donoma 1.6. so you may want to delete this table.

when you read this whole thread, you ca see that there are several people who have problems with there sonoma. but in the end they all managed it. so, maybe have a look at their postings.
for example, someone says that he needs to use 1599 as the frequency instead of 1600. maybe thats the problem. just look at your speedstep-centrino.c and try different versions.

then, if you don't got it, send me your speedstep-centrino.c and i will look at it.
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Sat Sep 10, 2005 3:47 pm

Hello,

I just recognized that the entry for the 730 processor was missing, so I copied BetterUnborn's into my speedstep-centrino.c, but now it doesn't compile any more. It just says:

Code: Select all

  CC      arch/i386/kernel/cpu/cpufreq/speedstep-centrino.o
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:346: error: `dothan_1599' unde
clared here (not in a function)
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:346: error: initializer elemen
t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:346: error: (near initializati
on for `models[13].op_points')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:346: error: initializer elemen
t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:346: error: (near initializati
on for `models[13]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:347: error: initializer elemen
t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:347: error: (near initializati
on for `models[14]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:348: error: initializer elemen
t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:348: error: (near initializati
on for `models[15]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:349: error: initializer elemen
t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:349: error: (near initializati
on for `models[16]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:350: error: initializer elemen
t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:350: error: (near initializati
on for `models[17]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:353: error: initializer elemen
t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:353: error: (near initializati                                                                                          on for `models[18]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:354: error: initializer elemen                                                                                          t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:354: error: (near initializati                                                                                          on for `models[19]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:355: error: initializer elemen                                                                                          t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:355: error: (near initializati                                                                                          on for `models[20]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:356: error: initializer elemen                                                                                          t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:356: error: (near initializati                                                                                          on for `models[21]')
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:358: error: initializer elemen                                                                                          t is not constant
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:358: error: (near initializati                                                                                          on for `models[22]')
make[3]: *** [arch/i386/kernel/cpu/cpufreq/speedstep-centrino.o] Fehler 1
make[2]: *** [arch/i386/kernel/cpu/cpufreq] Fehler 2
make[1]: *** [arch/i386/kernel/cpu] Fehler 2

My speedstep-centrino.c

Code: Select all

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/compiler.h>

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif

#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>

#include "speedstep-est-common.h"

#define PFX		"speedstep-centrino: "
#define MAINTAINER	"Jeremy Fitzhardinge <jeremy@goop.org>"

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)


struct cpu_id
{
	__u8	x86;            /* CPU family */
	__u8	x86_model;	/* model */
	__u8	x86_mask;	/* stepping */
};

enum {
	CPU_BANIAS,
	CPU_DOTHAN_A1,
	CPU_DOTHAN_A2,
	CPU_DOTHAN_B0,
	CPU_DOTHAN_C0,
};

static const struct cpu_id cpu_ids[] = {
	[CPU_BANIAS]	= { 6,  9, 5 },
	[CPU_DOTHAN_A1]	= { 6, 13, 1 },
	[CPU_DOTHAN_A2]	= { 6, 13, 2 },
	[CPU_DOTHAN_B0]	= { 6, 13, 6 },
	[CPU_DOTHAN_C0]	= { 6, 13, 8 },
};
#define N_IDS	(sizeof(cpu_ids)/sizeof(cpu_ids[0]))

struct cpu_model
{
	const struct cpu_id *cpu_id;
	const char	*model_name;
	unsigned	max_freq; /* max clock in kHz */

	struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
};
static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);

/* Operating points for current CPU */
static struct cpu_model *centrino_model[NR_CPUS];
static const struct cpu_id *centrino_cpu[NR_CPUS];

static struct cpufreq_driver centrino_driver;

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE

/* Computes the correct form for IA32_PERF_CTL MSR for a particular
   frequency/voltage operating point; frequency in MHz, volts in mV.
   This is stored as "index" in the structure. */
#define OP(mhz, mv)							\
	{								\
		.frequency = (mhz) * 1000,				\
		.index = (((mhz)/100) << 8) | ((mv - 700) / 16)		\
	}

/*
 * These voltage tables were derived from the Intel Pentium M
 * datasheet, document 25261202.pdf, Table 5.  I have verified they
 * are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
 * M.
 */

/* Ultra Low Voltage Intel Pentium M processor 900MHz (Banias) */
static struct cpufreq_frequency_table banias_900[] =
{
	OP(600,  844),
	OP(800,  988),
	OP(900, 1004),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Ultra Low Voltage Intel Pentium M processor 1000MHz (Banias) */
static struct cpufreq_frequency_table banias_1000[] =
{
	OP(600,   844),
	OP(800,   972),
	OP(900,   988),
	OP(1000, 1004),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Low Voltage Intel Pentium M processor 1.10GHz (Banias) */
static struct cpufreq_frequency_table banias_1100[] =
{
	OP( 600,  956),
	OP( 800, 1020),
	OP( 900, 1100),
	OP(1000, 1164),
	OP(1100, 1180),
	{ .frequency = CPUFREQ_TABLE_END }
};


/* Low Voltage Intel Pentium M processor 1.20GHz (Banias) */
static struct cpufreq_frequency_table banias_1200[] =
{
	OP( 600,  956),
	OP( 800, 1004),
	OP( 900, 1020),
	OP(1000, 1100),
	OP(1100, 1164),
	OP(1200, 1180),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.30GHz (Banias) */
static struct cpufreq_frequency_table banias_1300[] =
{
	OP( 600,  956),
	OP( 800, 1260),
	OP(1000, 1292),
	OP(1200, 1356),
	OP(1300, 1388),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.40GHz (Banias) */
static struct cpufreq_frequency_table banias_1400[] =
{
	OP( 600,  956),
	OP( 800, 1180),
	OP(1000, 1308),
	OP(1200, 1436),
	OP(1400, 1484),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.50GHz (Banias) */
static struct cpufreq_frequency_table banias_1500[] =
{
	OP( 600,  956),
	OP( 800, 1116),
	OP(1000, 1228),
	OP(1200, 1356),
	OP(1400, 1452),
	OP(1500, 1484),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.60GHz (Banias) */
static struct cpufreq_frequency_table banias_1600[] =
{
	OP( 600,  956),
	OP( 800, 1036),
	OP(1000, 1164),
	OP(1200, 1276),
	OP(1400, 1420),
	OP(1600, 1484),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.70GHz (Banias) */
static struct cpufreq_frequency_table banias_1700[] =
{
	OP( 600,  956),
	OP( 800, 1004),
	OP(1000, 1116),
	OP(1200, 1228),
	OP(1400, 1308),
	OP(1700, 1484),
	{ .frequency = CPUFREQ_TABLE_END }
};
#undef OP

/* Dothan processor datasheet 30218903.pdf defines 4 voltages for each
   frequency (VID#A through VID#D) - this macro allows us to define all
   of these but we only use the VID#C voltages at compile time - this may
   need some work if we want to select the voltage profile at runtime. */

#define OP(mhz, mva, mvb, mvc, mvd)					\
	{								\
		.frequency = (mhz) * 1000,				\
		.index = (((mhz)/100) << 8) | ((mvc - 700) / 16)       	\
	}

 /* Intel Pentium M processor 733 / 1.10GHz (Dothan) */
 static struct cpufreq_frequency_table dothan_1100[] =
{
 	OP( 500, 700, 700, 700, 700),
 	OP( 600, 700, 700, 700, 700),
 	OP( 800, 748, 748, 748, 748),
 	OP( 900, 764, 764, 764, 764),
 	OP(1000, 812, 812, 812, 812),
 	OP(1100, 844, 844, 844, 844),
 	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 710 / 1.40GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1400[] =
{

	OP( 400,  700,  700,  700,  700),
	OP( 600,  700,  700,  700,  700),
	OP( 800,  750,  750,  750,  750),
	OP(1000,  810,  810,  810,  810),
	OP(1200,  870,  870,  870,  870),
	OP(1400,  920,  920,  920,  920),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 715 / 1.50GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1500[] =
{
	OP( 600,  988,  988,  988,  988),
	OP( 800, 1068, 1068, 1068, 1052),
	OP(1000,  700, 1148, 1132, 1116),
	OP(1200, 1228, 1212, 1212, 1180),
	OP(1500, 1340, 1324, 1308, 1276),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 725 / 1.60GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1600[] =
{
	OP( 600,  800,  988,  988,  988),
	OP( 800,  800, 1068, 1052, 1052),
	OP(1000, 1132, 1132, 1116, 1116),
	OP(1200, 1212, 1196, 1180, 1164),
	OP(1400, 1276, 1260, 1244, 1228),
	OP(1600, 1340, 1324, 1308, 1276),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 735 / 1.70GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1700[] =
{
	OP( 600,  988,  988,  988,  988),
	OP( 800, 1052, 1052, 1052, 1052),
	OP(1000, 1116, 1116, 1116, 1100),
	OP(1200, 1180, 1180, 1164, 1148),
	OP(1400, 1244, 1244, 1228, 1212),
	OP(1700, 1340, 1324, 1308, 1276),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 745 / 1.80GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1800[] =
{
	OP( 600,  988,  988,  988,  988),
	OP( 800, 1052, 1052, 1052, 1036),
	OP(1000, 1116, 1100, 1100, 1084),
	OP(1200, 1164, 1164, 1148, 1132),
	OP(1400, 1228, 1212, 1212, 1180),
	OP(1600, 1292, 1276, 1260, 1228),
	OP(1800, 1340, 1324, 1308, 1276),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 755 / 2.00GHz (Dothan) */
static struct cpufreq_frequency_table dothan_2000[] =
{
	OP( 600,  988,  988,  988,  988),
	OP( 800, 1052, 1036, 1036, 1036),
	OP(1000, 1100, 1084, 1084, 1084),
	OP(1200, 1148, 1132, 1132, 1116),
	OP(1400, 1196, 1180, 1180, 1164),
	OP(1600, 1244, 1228, 1228, 1196),
	OP(1800, 1292, 1276, 1276, 1244),
	OP(2000, 1340, 1324, 1308, 1276),
	{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 730 / 1.599GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1599[] =
{
	OP( 600, 812, 812, 812, 812)
	OP( 800, 812, 812, 812, 812),
	OP(1067, 700, 700, 700, 700),
	OP(1333, 1004, 1004, 1004, 1004),
	OP(1600, 1100, 1100, 1100, 1100),
	{ .frequency = CPUFREQ_TABLE_END }
}; 

/* Intel Pentium M processor 750 / 1.86GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1867[] =
{
	OP( 800,  880,  880,  880,  880),
	OP(1333, 1010, 1010, 1010, 1010),
	OP(1867, 1120, 1120, 1120, 1120),
	{ .frequency = CPUFREQ_TABLE_END }
};

#undef OP

#define _BANIAS(cpuid, max, name)	\
{	.cpu_id		= cpuid,	\
	.model_name	= "Intel(R) Pentium(R) M processor " name "MHz", \
	.max_freq	= (max)*1000,	\
	.op_points	= banias_##max,	\
}
#define BANIAS(max)	_BANIAS(&cpu_ids[CPU_BANIAS], max, #max)

#define DOTHAN(cpuid, max, name)	\
{	.cpu_id		= cpuid,	\
	.model_name	= "Intel(R) Pentium(R) M processor " name "GHz", \
	.max_freq	= (max)*1000,	\
	.op_points	= dothan_##max,	\
}

/* CPU models, their operating frequency range, and freq/voltage
   operating points */
static struct cpu_model models[] =
{
	_BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"),
	BANIAS(1000),
	BANIAS(1100),
	BANIAS(1200),
	BANIAS(1300),
	BANIAS(1400),
	BANIAS(1500),
	BANIAS(1600),
	BANIAS(1700),
        DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1100, "1.10"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1400, "1.40"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1500, "1.50"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1600, "1.60"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1599, "1.60"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1700, "1.70"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1800, "1.80"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 2000, "2.00"),
	DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1867, "1.86"),

	/* NULL model_name is a wildcard */
	{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
	{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
	{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
	{ &cpu_ids[CPU_DOTHAN_C0], NULL, 0, NULL },

	{ NULL, }
};
#undef _BANIAS
#undef BANIAS
#undef DOTHAN
Top
knefas
l33t
l33t
User avatar
Posts: 828
Joined: Sun Dec 21, 2003 1:20 am

  • Quote

Post by knefas » Sat Sep 10, 2005 3:57 pm

try to remove

Code: Select all

DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1600, "1.60")
and change

Code: Select all

static struct cpufreq_frequency_table banias_1600[] = 
in

Code: Select all

static struct cpufreq_frequency_table banias_1599[] = 
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Sun Sep 11, 2005 11:32 am

Hi,

with the changes you've appointed and after I've fixed two other things, the kernel is compiling now, but says:

Code: Select all

arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:181: warning: `banias_1599' defined but not used
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c:253: warning: `dothan_1600' defined but not used
Let's see what a reboot will show, so long, thank you!
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Sun Sep 11, 2005 12:19 pm

It still doesn't work :(

I'm using cpufreq-info to check whether the kernel is using my new values or not, but it still says 800 - 1600Mhz. In the section for my processor I specified a 600Mhz line for testing purposes (I know that it won't be really used, but in that way, cpufreq-info will show me which definition it is using).

Any more hints?
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Sun Sep 11, 2005 4:30 pm

why have you defined a banias 1599?

i think you should post your complete speedstep-centrino.c again.

isn't anyone here, who has a working speedstep-centrino for the sonoma 1.6?

here the link to my working file for the dothan 1.4 and the sonoma 1.87:
http://www.math.uni-bielefeld.de/~schwa ... centrino.c


I think, the only changes you have to make are: uncomment the entries for the dothan 1.6 and change the entry for the 1.87 sonoma to your values and change the row for the sonoma in the "static struct cpu_model models" section.

i hope that will work.

edit: i looked another time at your posted file and i see that you have a wrong entry in the "static struct cpu_model models" section. because you have an sonoma with a 133 frontsidebus you have to use "C0" instead of "B0" (the same as in the line of the sonoma)
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Mon Sep 12, 2005 10:23 pm

Changing B0 into C0 resulted in the new kernel crashing each time KDE is loaded (when the Suse Bootscreen reappears with the mouse cursor on it saying "Starting User Interface"). I'm using BetterUnborn's voltages, is it possible that the kernel is finally using them and crashes therefore?

Where can I get the original values for my sonoma 730 cpu? I've browsed Intels datasheet but didn't find anything helfpful.

Thanks,
Matthias
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Tue Sep 13, 2005 12:21 am

it sounds like that!

just try to add 0.1 to each of the voltages.
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Tue Sep 13, 2005 11:19 am

It works!

Readjusting the voltages finally gave me a booting kernel that uses my custom voltages. Now I have to figure out the optimal values fpr my system, can anyone give me some hints to do so?

How can I set the frequency to a certain value? Suse only supports 800Mhz and 1600Mhz. Which programm can I use to check if my system is stable?

Thanks,
Matthias
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Tue Sep 13, 2005 12:25 pm

thats great!


think susu supports everything. (its nothing about the distri). if you use cpufreq, with cpufreq-info ou got all the information about the frequencies which are possible and about the governer you can use.

with cpufreq-set -g conservative (if you have installed it) your pc uses every voltage an is very battery saving.

just try out cpufreq-set and he gives you all the informations you need.
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Tue Sep 13, 2005 3:50 pm

ok, I managed to set the frequencies manually using cpufreq-set, but can you please tell me a programm that tests the cpu with full load? For WinXP, I use Prime95.

My speedstep-cenntrino.c,not perfect and I'm sure all that copy & paste during the last days left some unneccessary entries, but working for the sonoma 1,60Ghz (730):

/*
* cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium
* M (part of the Centrino chipset).
*
* Despite the "SpeedStep" in the name, this is almost entirely unlike
* traditional SpeedStep.
*
* Modelled on speedstep.c
*
* Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
*
* WARNING WARNING WARNING
*
* This driver manipulates the PERF_CTL MSR, which is only somewhat
* documented. While it seems to work on my laptop, it has not been
* tested anywhere else, and it may not work for you, do strange
* things or simply crash.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/compiler.h>

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif

#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>

#include "speedstep-est-common.h"

#define PFX "speedstep-centrino: "
#define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>"

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)


struct cpu_id
{
__u8 x86; /* CPU family */
__u8 x86_model; /* model */
__u8 x86_mask; /* stepping */
};

enum {
CPU_BANIAS,
CPU_DOTHAN_A1,
CPU_DOTHAN_A2,
CPU_DOTHAN_B0,
CPU_DOTHAN_C0,
};

static const struct cpu_id cpu_ids[] = {
[CPU_BANIAS] = { 6, 9, 5 },
[CPU_DOTHAN_A1] = { 6, 13, 1 },
[CPU_DOTHAN_A2] = { 6, 13, 2 },
[CPU_DOTHAN_B0] = { 6, 13, 6 },
[CPU_DOTHAN_C0] = { 6, 13, 8 },
};
#define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0]))

struct cpu_model
{
const struct cpu_id *cpu_id;
const char *model_name;
unsigned max_freq; /* max clock in kHz */

struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
};
static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);

/* Operating points for current CPU */
static struct cpu_model *centrino_model[NR_CPUS];
static const struct cpu_id *centrino_cpu[NR_CPUS];

static struct cpufreq_driver centrino_driver;

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE

/* Computes the correct form for IA32_PERF_CTL MSR for a particular
frequency/voltage operating point; frequency in MHz, volts in mV.
This is stored as "index" in the structure. */
#define OP(mhz, mv) \
{ \
.frequency = (mhz) * 1000, \
.index = (((mhz)/100) << 8) | ((mv - 700) / 16) \
}

/*
* These voltage tables were derived from the Intel Pentium M
* datasheet, document 25261202.pdf, Table 5. I have verified they
* are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
* M.
*/

/* Ultra Low Voltage Intel Pentium M processor 900MHz (Banias) */
static struct cpufreq_frequency_table banias_900[] =
{
OP(600, 844),
OP(800, 988),
OP(900, 1004),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Ultra Low Voltage Intel Pentium M processor 1000MHz (Banias) */
static struct cpufreq_frequency_table banias_1000[] =
{
OP(600, 844),
OP(800, 972),
OP(900, 988),
OP(1000, 1004),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Low Voltage Intel Pentium M processor 1.10GHz (Banias) */
static struct cpufreq_frequency_table banias_1100[] =
{
OP( 600, 956),
OP( 800, 1020),
OP( 900, 1100),
OP(1000, 1164),
OP(1100, 1180),
{ .frequency = CPUFREQ_TABLE_END }
};


/* Low Voltage Intel Pentium M processor 1.20GHz (Banias) */
static struct cpufreq_frequency_table banias_1200[] =
{
OP( 600, 956),
OP( 800, 1004),
OP( 900, 1020),
OP(1000, 1100),
OP(1100, 1164),
OP(1200, 1180),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.30GHz (Banias) */
static struct cpufreq_frequency_table banias_1300[] =
{
OP( 600, 956),
OP( 800, 1260),
OP(1000, 1292),
OP(1200, 1356),
OP(1300, 1388),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.40GHz (Banias) */
static struct cpufreq_frequency_table banias_1400[] =
{
OP( 600, 956),
OP( 800, 1180),
OP(1000, 1308),
OP(1200, 1436),
OP(1400, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.50GHz (Banias) */
static struct cpufreq_frequency_table banias_1500[] =
{
OP( 600, 956),
OP( 800, 1116),
OP(1000, 1228),
OP(1200, 1356),
OP(1400, 1452),
OP(1500, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.60GHz (Banias) */
static struct cpufreq_frequency_table banias_1599[] =
{
OP( 600, 956),
OP( 800, 1036),
OP(1000, 1164),
OP(1200, 1276),
OP(1400, 1420),
OP(1600, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 1.70GHz (Banias) */
static struct cpufreq_frequency_table banias_1700[] =
{
OP( 600, 956),
OP( 800, 1004),
OP(1000, 1116),
OP(1200, 1228),
OP(1400, 1308),
OP(1700, 1484),
{ .frequency = CPUFREQ_TABLE_END }
};
#undef OP

/* Dothan processor datasheet 30218903.pdf defines 4 voltages for each
frequency (VID#A through VID#D) - this macro allows us to define all
of these but we only use the VID#C voltages at compile time - this may
need some work if we want to select the voltage profile at runtime. */

#define OP(mhz, mva, mvb, mvc, mvd) \
{ \
.frequency = (mhz) * 1000, \
.index = (((mhz)/100) << 8) | ((mvc - 700) / 16) \
}

/* Intel Pentium M processor 733 / 1.10GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1100[] =
{
OP( 500, 700, 700, 700, 700),
OP( 600, 700, 700, 700, 700),
OP( 800, 748, 748, 748, 748),
OP( 900, 764, 764, 764, 764),
OP(1000, 812, 812, 812, 812),
OP(1100, 844, 844, 844, 844),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 710 / 1.40GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1400[] =
{

OP( 400, 700, 700, 700, 700),
OP( 600, 700, 700, 700, 700),
OP( 800, 750, 750, 750, 750),
OP(1000, 810, 810, 810, 810),
OP(1200, 870, 870, 870, 870),
OP(1400, 920, 920, 920, 920),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 715 / 1.50GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1500[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1068, 1068, 1068, 1052),
OP(1000, 700, 1148, 1132, 1116),
OP(1200, 1228, 1212, 1212, 1180),
OP(1500, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 725 / 1.60GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1600[] =
{
OP( 600, 800, 988, 988, 988),
OP( 800, 800, 1068, 1052, 1052),
OP(1000, 1132, 1132, 1116, 1116),
OP(1200, 1212, 1196, 1180, 1164),
OP(1400, 1276, 1260, 1244, 1228),
OP(1600, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 735 / 1.70GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1700[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1052, 1052, 1052, 1052),
OP(1000, 1116, 1116, 1116, 1100),
OP(1200, 1180, 1180, 1164, 1148),
OP(1400, 1244, 1244, 1228, 1212),
OP(1700, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 745 / 1.80GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1800[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1052, 1052, 1052, 1036),
OP(1000, 1116, 1100, 1100, 1084),
OP(1200, 1164, 1164, 1148, 1132),
OP(1400, 1228, 1212, 1212, 1180),
OP(1600, 1292, 1276, 1260, 1228),
OP(1800, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 755 / 2.00GHz (Dothan) */
static struct cpufreq_frequency_table dothan_2000[] =
{
OP( 600, 988, 988, 988, 988),
OP( 800, 1052, 1036, 1036, 1036),
OP(1000, 1100, 1084, 1084, 1084),
OP(1200, 1148, 1132, 1132, 1116),
OP(1400, 1196, 1180, 1180, 1164),
OP(1600, 1244, 1228, 1228, 1196),
OP(1800, 1292, 1276, 1276, 1244),
OP(2000, 1340, 1324, 1308, 1276),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 730 / 1.599GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1599[] =
{
OP( 800, 812, 912, 912, 912),
OP(1067, 1104, 1104, 1104, 1104),
OP(1333, 1104, 1104, 1104, 1104),
OP(1600, 1200, 1200, 1200, 1200),
{ .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 750 / 1.86GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1867[] =
{
OP( 800, 880, 880, 880, 880),
OP(1333, 1010, 1010, 1010, 1010),
OP(1867, 1120, 1120, 1120, 1120),
{ .frequency = CPUFREQ_TABLE_END }
};

#undef OP

#define _BANIAS(cpuid, max, name) \
{ .cpu_id = cpuid, \
.model_name = "Intel(R) Pentium(R) M processor " name "MHz", \
.max_freq = (max)*1000, \
.op_points = banias_##max, \
}
#define BANIAS(max) _BANIAS(&cpu_ids[CPU_BANIAS], max, #max)

#define DOTHAN(cpuid, max, name) \
{ .cpu_id = cpuid, \
.model_name = "Intel(R) Pentium(R) M processor " name "GHz", \
.max_freq = (max)*1000, \
.op_points = dothan_##max, \
}

/* CPU models, their operating frequency range, and freq/voltage
operating points */
static struct cpu_model models[] =
{
_BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"),
BANIAS(1000),
BANIAS(1100),
BANIAS(1200),
BANIAS(1300),
BANIAS(1400),
BANIAS(1500),
BANIAS(1700),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1100, "1.10"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1400, "1.40"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1500, "1.50"),
DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1599, "1.60"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1700, "1.70"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 1800, "1.80"),
DOTHAN(&cpu_ids[CPU_DOTHAN_B0], 2000, "2.00"),
DOTHAN(&cpu_ids[CPU_DOTHAN_C0], 1867, "1.86"),

/* NULL model_name is a wildcard */
{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
{ &cpu_ids[CPU_DOTHAN_C0], NULL, 0, NULL },

{ NULL, }
};
#undef _BANIAS
#undef BANIAS
#undef DOTHAN

static int centrino_cpu_init_table(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
struct cpu_model *model;

for(model = models; model->cpu_id != NULL; model++)
if (centrino_verify_cpu_id(cpu, model->cpu_id) &&
(model->model_name == NULL ||
strcmp(cpu->x86_model_id, model->model_name) == 0))
break;

if (model->cpu_id == NULL) {
/* No match at all */
dprintk(KERN_INFO PFX "no support for CPU model \"%s\": "
"send /proc/cpuinfo to " MAINTAINER "\n",
cpu->x86_model_id);
return -ENOENT;
}

if (model->op_points == NULL) {
/* Matched a non-match */
dprintk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
cpu->x86_model_id);
#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
#endif
return -ENOENT;
}

centrino_model[policy->cpu] = model;

dprintk("found \"%s\": max frequency: %dkHz\n",
model->model_name, model->max_freq);

return 0;
}

#else
static inline int centrino_cpu_init_table(struct cpufreq_policy *policy) { return -ENODEV; }
#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */

static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x)
{
if ((c->x86 == x->x86) &&
(c->x86_model == x->x86_model) &&
(c->x86_mask == x->x86_mask))
return 1;
return 0;
}

/* To be called only after centrino_model is initialized */
static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
{
int i;

/*
* Extract clock in kHz from PERF_CTL value
* for centrino, as some DSDTs are buggy.
* Ideally, this can be done using the acpi_data structure.
*/
if ((centrino_cpu[cpu] == &cpu_ids[CPU_BANIAS]) ||
(centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_A1]) ||
(centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_B0]) ||
(centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_C0])) {
msr = (msr >> 8) & 0xff;
return msr * 100000;
}

if ((!centrino_model[cpu]) || (!centrino_model[cpu]->op_points))
return 0;

msr &= 0xffff;
for (i=0;centrino_model[cpu]->op_points.frequency != CPUFREQ_TABLE_END; i++) {
if (msr == centrino_model[cpu]->op_points.index)
return centrino_model[cpu]->op_points.frequency;
}
if (failsafe)
return centrino_model[cpu]->op_points[i-1].frequency;
else
return 0;
}

/* Return the current CPU frequency in kHz */
static unsigned int get_cur_freq(unsigned int cpu)
{
unsigned l, h;
unsigned clock_freq;
cpumask_t saved_mask;

saved_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu)
return 0;

rdmsr(MSR_IA32_PERF_STATUS, l, h);
clock_freq = extract_clock(l, cpu, 0);

if (unlikely(clock_freq == 0)) {
/*
* On some CPUs, we can see transient MSR values (which are
* not present in _PSS), while CPU is doing some automatic
* P-state transition (like TM2). Get the last freq set
* in PERF_CTL.
*/
rdmsr(MSR_IA32_PERF_CTL, l, h);
clock_freq = extract_clock(l, cpu, 1);
}

set_cpus_allowed(current, saved_mask);
return clock_freq;
}


#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI

static struct acpi_processor_performance p;

/*
* centrino_cpu_init_acpi - register with ACPI P-States library
*
* Register with the ACPI P-States library (part of drivers/acpi/processor.c)
* in order to determine correct frequency and voltage pairings by reading
* the _PSS of the ACPI DSDT or SSDT tables.
*/
static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
{
union acpi_object arg0 = {ACPI_TYPE_BUFFER};
u32 arg0_buf[3];
struct acpi_object_list arg_list = {1, &arg0};
unsigned long cur_freq;
int result = 0, i;
unsigned int cpu = policy->cpu;

/* _PDC settings */
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_EST_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_MSR;

p.pdc = &arg_list;

/* register with ACPI core */
if (acpi_processor_register_performance(&p, cpu)) {
dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");
return -EIO;
}

/* verify the acpi_data */
if (p.state_count <= 1) {
dprintk("No P-States\n");
result = -ENODEV;
goto err_unreg;
}

if ((p.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
(p.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
dprintk("Invalid control/status registers (%x - %x)\n",
p.control_register.space_id, p.status_register.space_id);
result = -EIO;
goto err_unreg;
}

for (i=0; i<p.state_count; i++) {
if (p.states.control != p.states.status) {
dprintk("Different control (%x) and status values (%x)\n",
p.states.control, p.states.status);
result = -EINVAL;
goto err_unreg;
}

if (!p.states.core_frequency) {
dprintk("Zero core frequency for state %u\n", i);
result = -EINVAL;
goto err_unreg;
}

if (p.states.core_frequency > p.states[0].core_frequency) {
dprintk("P%u has larger frequency (%u) than P0 (%u), skipping\n", i,
p.states.core_frequency, p.states[0].core_frequency);
p.states[i].core_frequency = 0;
continue;
}
}

centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
if (!centrino_model[cpu]) {
result = -ENOMEM;
goto err_unreg;
}
memset(centrino_model[cpu], 0, sizeof(struct cpu_model));

centrino_model[cpu]->model_name=NULL;
centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000;
centrino_model[cpu]->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) *
(p.state_count + 1), GFP_KERNEL);
if (!centrino_model[cpu]->op_points) {
result = -ENOMEM;
goto err_kfree;
}

for (i=0; i<p.state_count; i++) {
centrino_model[cpu]->op_points[i].index = p.states[i].control;
centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000;
dprintk("adding state %i with frequency %u and control value %04x\n",
i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
}
centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;

cur_freq = get_cur_freq(cpu);

for (i=0; i<p.state_count; i++) {
if (!p.states[i].core_frequency) {
dprintk("skipping state %u\n", i);
centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
continue;
}

if (extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0) !=
(centrino_model[cpu]->op_points[i].frequency)) {
dprintk("Invalid encoded frequency (%u vs. %u)\n",
extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0),
centrino_model[cpu]->op_points[i].frequency);
result = -EINVAL;
goto err_kfree_all;
}

if (cur_freq == centrino_model[cpu]->op_points[i].frequency)
p.state = i;
}

/* notify BIOS that we exist */
acpi_processor_notify_smm(THIS_MODULE);

return 0;

err_kfree_all:
kfree(centrino_model[cpu]->op_points);
err_kfree:
kfree(centrino_model[cpu]);
err_unreg:
acpi_processor_unregister_performance(&p, cpu);
dprintk(KERN_INFO PFX "invalid ACPI data\n");
return (result);
}
#else
static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; }
#endif

static int centrino_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
unsigned freq;
unsigned l, h;
int ret;
int i;

/* Only Intel makes Enhanced Speedstep-capable CPUs */
if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST))
return -ENODEV;

for (i = 0; i < N_IDS; i++)
if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
break;

if (i != N_IDS)
centrino_cpu[policy->cpu] = &cpu_ids[i];

if (is_const_loops_cpu(policy->cpu)) {
centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
}

if (centrino_cpu_init_acpi(policy)) {
if (policy->cpu != 0)
return -ENODEV;

if (!centrino_cpu[policy->cpu]) {
dprintk(KERN_INFO PFX "found unsupported CPU with "
"Enhanced SpeedStep: send /proc/cpuinfo to "
MAINTAINER "\n");
return -ENODEV;
}

if (centrino_cpu_init_table(policy)) {
return -ENODEV;
}
}

/* Check to see if Enhanced SpeedStep is enabled, and try to
enable it if not. */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);

if (!(l & (1<<16))) {
l |= (1<<16);
dprintk("trying to enable Enhanced SpeedStep (%x)\n", l);
wrmsr(MSR_IA32_MISC_ENABLE, l, h);

/* check to see if it stuck */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
if (!(l & (1<<16))) {
printk(KERN_INFO PFX "couldn't enable Enhanced SpeedStep\n");
return -ENODEV;
}
}

freq = get_cur_freq(policy->cpu);

policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */
policy->cur = freq;

dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);

ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model[policy->cpu]->op_points);
if (ret)
return (ret);

cpufreq_frequency_table_get_attr(centrino_model[policy->cpu]->op_points, policy->cpu);

return 0;
}

static int centrino_cpu_exit(struct cpufreq_policy *policy)
{
unsigned int cpu = policy->cpu;

if (!centrino_model[cpu])
return -ENODEV;

cpufreq_frequency_table_put_attr(cpu);

#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
if (!centrino_model[cpu]->model_name) {
dprintk("unregistering and freeing ACPI data\n");
acpi_processor_unregister_performance(&p, cpu);
kfree(centrino_model[cpu]->op_points);
kfree(centrino_model[cpu]);
}
#endif

centrino_model[cpu] = NULL;

return 0;
}

/**
* centrino_verify - verifies a new CPUFreq policy
* @policy: new policy
*
* Limit must be within this model's frequency range at least one
* border included.
*/
static int centrino_verify (struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, centrino_model[policy->cpu]->op_points);
}

/**
* centrino_setpolicy - set a new CPUFreq policy
* @policy: new policy
* @target_freq: the target frequency
* @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* Sets a new CPUFreq policy.
*/
static int centrino_target (struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate = 0;
unsigned int msr, oldmsr, h, cpu = policy->cpu;
struct cpufreq_freqs freqs;
cpumask_t saved_mask;
int retval;

if (centrino_model[cpu] == NULL)
return -ENODEV;

/*
* Support for SMP systems.
* Make sure we are running on the CPU that wants to change frequency
*/
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, policy->cpus);
if (!cpu_isset(smp_processor_id(), policy->cpus)) {
dprintk("couldn't limit to CPUs in this domain\n");
return(-EAGAIN);
}

if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq,
relation, &newstate)) {
retval = -EINVAL;
goto migrate_end;
}

msr = centrino_model[cpu]->op_points[newstate].index;
rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);

if (msr == (oldmsr & 0xffff)) {
retval = 0;
dprintk("no change needed - msr was and needs to be %x\n", oldmsr);
goto migrate_end;
}

freqs.cpu = cpu;
freqs.old = extract_clock(oldmsr, cpu, 0);
freqs.new = extract_clock(msr, cpu, 0);

dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
target_freq, freqs.old, freqs.new, msr);

cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);

/* all but 16 LSB are "reserved", so treat them with
care */
oldmsr &= ~0xffff;
msr &= 0xffff;
oldmsr |= msr;

wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);

cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);

retval = 0;
migrate_end:
set_cpus_allowed(current, saved_mask);
return (retval);
}

static struct freq_attr* centrino_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};

static struct cpufreq_driver centrino_driver = {
.name = "centrino", /* should be speedstep-centrino,
but there's a 16 char limit */
.init = centrino_cpu_init,
.exit = centrino_cpu_exit,
.verify = centrino_verify,
.target = centrino_target,
.get = get_cur_freq,
.attr = centrino_attr,
.owner = THIS_MODULE,
};


/**
* centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
*
* Initializes the Enhanced SpeedStep support. Returns -ENODEV on
* unsupported devices, -ENOENT if there's no voltage table for this
* particular CPU model, -EINVAL on problems during initiatization,
* and zero on success.
*
* This is quite picky. Not only does the CPU have to advertise the
* "est" flag in the cpuid capability flags, we look for a specific
* CPU model and stepping, and we need to have the exact model name in
* our voltage tables. That is, be paranoid about not releasing
* someone's valuable magic smoke.
*/
static int __init centrino_init(void)
{
struct cpuinfo_x86 *cpu = cpu_data;

if (!cpu_has(cpu, X86_FEATURE_EST))
return -ENODEV;

return cpufreq_register_driver(&centrino_driver);
}

static void __exit centrino_exit(void)
{
cpufreq_unregister_driver(&centrino_driver);
}

MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>");
MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors.");
MODULE_LICENSE ("GPL");

late_initcall(centrino_init);
module_exit(centrino_exit);
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Tue Sep 13, 2005 8:54 pm

prime 95 is also available for linux.

with gentoo just type "emerge gimps"

then start it with "prime"

the rest is as easy as in windows (but its textmode only).

with any other distri, just search for gimps or prime95 in the package manager.


thanks for your speedstep-centrino.c
i think because you don't delete the other entries your file should work for all dothan and for the 1.6 and 1.87 sonoma. so, i hope it will be helpful for lots of other persons.
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Tue Sep 13, 2005 10:40 pm

Are there any other programs out there? I didn't manage to get Prime95 to work, it says

Code: Select all

./mprime: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
despite the fact that libstdc is installed! (mprime in home directory, I didn't find any installation instructions)
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Wed Sep 14, 2005 2:50 am

sorry, i don't know how to install it, because with gentoo everything is so easy.


i don't think there are very much programs for this testings for linux, because normally only overclocker need them and oveclocker usually use windows.


can't you install it via the suse packetmanager?
Top
Matt.Shure
n00b
n00b
Posts: 11
Joined: Tue Sep 06, 2005 4:35 pm

  • Quote

Post by Matt.Shure » Wed Sep 14, 2005 3:30 pm

No, the Suse packet manager finds nothing for "gimps" or "prime" :(
Top
schorsche
Apprentice
Apprentice
Posts: 230
Joined: Thu Jan 27, 2005 12:55 am

  • Quote

Post by schorsche » Thu Sep 29, 2005 12:09 pm

rschwarze,

Do I just need to copy your speedstep-centrino.c - file with all the entries for different CPU's or
do I have to cancel all the other for different cpu's out?

I'm using a Dothan 1500 CPU, recompiled the kernel as you sain (disabling the ACPI-Option)
but it's not working.

Code: Select all

/* Intel Pentium M processor 710 / 1.40GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1400[] =
{
        OP( 600, 700, 700, 700, 700),
        OP( 800, 770, 770, 770, 769),
        OP(1000, 840, 840, 840, 840),
        OP(1200, 910, 910, 910, 910),
        OP(1400, 980, 980, 980, 980),
        { .frequency = CPUFREQ_TABLE_END }
};

/* Intel Pentium M processor 715 / 1.50GHz (Dothan) */
static struct cpufreq_frequency_table dothan_1500[] =
{
        OP( 600, 700, 700, 700, 700),
        OP( 800, 1068, 1068, 1068, 1052),
        OP(1000, 1148, 1148, 1132, 1116),
        OP(1200, 1228, 1212, 1212, 1180),
        OP(1500, 1340, 1324, 1308, 1276),
        { .frequency = CPUFREQ_TABLE_END }
};


cpuinfo shows

Code: Select all

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 13
model name      : Intel(R) Pentium(R) M processor 1.50GHz
stepping        : 8
cpu MHz         : 599.642
cache size      : 2048 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov                                                                  pat clflush dts acpi mmx fxsr sse sse2 ss tm pbe nx est tm2
bogomips        : 1189.47
Thanks very much
Top
rschwarze
n00b
n00b
Posts: 63
Joined: Fri Jul 01, 2005 12:26 pm
Location: Germany

  • Quote

Post by rschwarze » Thu Sep 29, 2005 5:29 pm

Yes, you can use my speedstep-centrino.c file. you don't have to change anything than your voltages.

why do you know it is not working?

what is the output of cpufreq-info?

and while compiling the new kernel, do you see the line where he compiles the speedstep-centrino.c?

have you read this whole thread? there might me many useful hints ;)
Top
Post Reply

340 posts
  • Page 3 of 14
    • Jump to page:
  • Previous
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 14
  • Next

Return to “Kernel & Hardware”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy

 

 

magic