* writing a cpufreq driver
@ 2006-09-21 18:48 Ryan Underwood
2006-09-21 19:31 ` Dave Jones
2006-09-22 15:39 ` Bruno Ducrot
0 siblings, 2 replies; 29+ messages in thread
From: Ryan Underwood @ 2006-09-21 18:48 UTC (permalink / raw)
To: Cpufreq
[-- Attachment #1: Type: text/plain, Size: 924 bytes --]
I wrote a cpufreq target driver for older Toshiba laptops. It uses SMM
to change between a "fast" and a "slow" processing speed. I have two
remaining bugs. Any comments would be appreciated.
1. The first time cpufreq changes speed, I get the whole "Losing some
ticks... checking if CPU frequency changed." then eventually "Losing too
many ticks!" and timer switches to PIT. This does not happen when I use
the /dev/toshiba driver to change speeds from userspace. Not sure what
is going on here... SMI handler latency is between 6 and 7 ms.
2. The current CPU frequency is stored in NVRAM by the SMI handler.
Unfortunately, this means if cpufreq throttles the CPU and the system is
then rebooted, the boot process is exceedingly slow. Is there some sane
way to hook into the shutdown process to restore the appropriate values,
or is this something I have to live with?
--
Ryan Underwood, <nemesis@icequake.net>
[-- Attachment #2: toshiba_freq.c --]
[-- Type: text/x-csrc, Size: 11885 bytes --]
/*
* toshiba_freq.c: cpufreq driver for Toshiba SCI (non-Speedstep) laptops
*
* Copyright (C) 2006 Ryan Underwood <nemesis@icequake.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Based on sc520_freq.c
*
* 2006-09-11: - initial revision
*/
/* NOTE: currently this should drag in toshiba.ko which checks for the
* appropriate hardware in its init function. Things will be different when
* ACPI instead of the SMM driver is used as the SCI access method. */
/* FIXME: Fan and LCD brightness are variable on some systems */
/* FIXME: TSC timer needs recalibration, why isn't this an issue with /dev/toshiba? */
/* FIXME: on reboot (Esp SysRq) how to restore state? */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timex.h>
#include <linux/delay.h>
#include <linux/cpufreq.h>
#include <linux/toshiba.h>
#define DRIVER_NAME "toshiba_freq"
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg)
static u32 original_battsave;
static u32 original_cpustate;
static u32 original_cache;
static u32 original_brightness;
static u32 original_fan;
/* Store this locally to avoid a SMM round trip to obtain it */
static u32 current_cpustate;
/* The operating speed of the CPU when in 'fast' mode */
static int nominal_khz;
/* The maximum SMI interrupt latency we have encountered */
static int max_smm_latency = 7000000; /* Start with 7ms */
/* Has an SCI error occurred in the past? */
static int sci_error;
static int control_cpucache = 1;
static int control_fan = 1;
static int control_lcd;
/* User-supplied nominal MHz rating */
static int user_mhz = -1;
module_param_named(cpucache, control_cpucache, int, 1);
MODULE_PARM_DESC(cpucache, "Allow CPUFreq to enable/disable CPU cache");
module_param_named(fan, control_fan, int, 1);
MODULE_PARM_DESC(fan, "Allow CPUFreq to control the system fan");
module_param_named(lcd, control_lcd, int, 0);
MODULE_PARM_DESC(lcd, "Allow CPUFreq to control LCD brightness");
module_param_named(mhz, user_mhz, int, -1);
MODULE_PARM_DESC(mhz, "MHz rating of CPU (required for pre-Pentium)");
/* Index corresponds to the SCI CPU speed state (0 or 1) */
static struct cpufreq_frequency_table toshiba_freq_table[] = {
{0, 0}, /* slow (low) */
{1, 0}, /* fast (high) */
{0, CPUFREQ_TABLE_END},
};
static void restore_original_config(void)
{
/* When an error condition is set, the config has already
* been restored */
if (sci_error) return;
if (control_fan)
tosh_scihci_set(HCI_SET, HCI_FAN, original_fan);
if (control_lcd)
tosh_scihci_set(0, SCI_LCD_BRIGHTNESS, original_brightness);
if (control_cpucache)
tosh_scihci_set(0, SCI_CPU_CACHE, original_cache);
tosh_scihci_set(0, SCI_PROCESSING, original_cpustate);
tosh_scihci_set(0, SCI_BATTERY_SAVE, original_battsave);
}
static unsigned int toshiba_freq_get_cpu_frequency(unsigned int cpu)
{
#if 0
unsigned int val;
tosh_scihci_get(0, SCI_PROCESSING, &val);
val &= 1; /* safety */
return toshiba_freq_table[val].frequency;
#else
/* It is okay to cache this, as long as userland is
* prevented from messing with the current state via
* /dev/toshiba. */
return toshiba_freq_table[current_cpustate].frequency;
#endif
}
static void tosh_scihci_set_error(unsigned int hci, unsigned int cmd, unsigned int arg)
{
int err;
int transition_usecs;
struct timeval tv, tv2;
if (sci_error) return;
do_gettimeofday(&tv);
err = tosh_scihci_set(hci, cmd, arg);
do_gettimeofday(&tv2);
transition_usecs = 1000000*(tv2.tv_sec - tv.tv_sec) + (tv2.tv_usec - tv.tv_usec);
if (transition_usecs*1000 > max_smm_latency) { /* latency is in ns */
dprintk(DRIVER_NAME": transition latency increased from %d to %d ns\n", max_smm_latency, transition_usecs*1000);
max_smm_latency = transition_usecs * 1000;
}
if (err) {
printk(DRIVER_NAME": SCI error condition encountered, giving up.\n");
/* Attempt to restore the original config, so i.e. the
* processor is not at high speed while the fan is not on,
* or some other inconsistent state. */
restore_original_config();
/* We will do nothing more now */
tosh_cpufreq_in_control = 0;
sci_error = 1;
}
}
static void toshiba_freq_set_cpu_state (unsigned int state)
{
struct cpufreq_freqs freqs;
freqs.old = toshiba_freq_get_cpu_frequency(0);
freqs.new = toshiba_freq_table[state].frequency;
freqs.cpu = 0;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
dprintk(DRIVER_NAME": attempting to set frequency to %i kHz\n",
toshiba_freq_table[state].frequency);
if (state == 0) { /* slow */
if (control_fan)
tosh_scihci_set_error(HCI_SET, HCI_FAN, HCI_DISABLE);
if (control_lcd)
tosh_scihci_set_error(0, SCI_LCD_BRIGHTNESS, SCI_SEMI_BRIGHT);
if (control_cpucache)
tosh_scihci_set_error(0, SCI_CPU_CACHE, SCI_OFF);
tosh_scihci_set_error(0, SCI_PROCESSING, SCI_LOW);
}
else { /* fast */
if (control_fan)
tosh_scihci_set_error(HCI_SET, HCI_FAN, HCI_ENABLE);
if (control_lcd)
tosh_scihci_set_error(0, SCI_LCD_BRIGHTNESS, SCI_BRIGHT);
if (control_cpucache)
tosh_scihci_set_error(0, SCI_CPU_CACHE, SCI_ON);
#if 0
tosh_scihci_set_error(0, SCI_PROCESSING, SCI_HIGH);
#else
{
//Experimenting with SMM latency
u32 low, low2;
local_irq_disable();
sync_core();
low = get_cycles();
tosh_scihci_set_error(0, SCI_PROCESSING, SCI_HIGH);
sync_core();
low2 = get_cycles();
local_irq_enable();
dprintk(DRIVER_NAME": SMM took %d cycles\n", low2-low);
}
#endif
}
current_cpustate = toshiba_freq_table[state].index;
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
};
static int toshiba_freq_verify (struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, &toshiba_freq_table[0]);
}
static int toshiba_freq_target (struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate = 0;
if (cpufreq_frequency_table_target(policy, toshiba_freq_table, target_freq, relation, &newstate))
return -EINVAL;
toshiba_freq_set_cpu_state(newstate);
policy->cpuinfo.transition_latency = max_smm_latency;
return 0;
}
/*
* Module init and exit code
*/
static int toshiba_freq_cpu_init(struct cpufreq_policy *policy)
{
int result;
/* Prevent userspace from using /dev/toshiba to frob the CPU speed */
tosh_cpufreq_in_control = 1;
/* Fill out the frequency table (in KHz) for the two Toshiba SCI modes
* "slow" and "fast". */
toshiba_freq_table[0].frequency = nominal_khz / 2;
toshiba_freq_table[1].frequency = nominal_khz;
/* cpuinfo and default policy values */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = max_smm_latency;
policy->cur = toshiba_freq_get_cpu_frequency(0);
result = cpufreq_frequency_table_cpuinfo(policy, toshiba_freq_table);
if (result)
return (result);
cpufreq_frequency_table_get_attr(toshiba_freq_table, policy->cpu);
return 0;
}
static int toshiba_freq_cpu_exit(struct cpufreq_policy *policy)
{
cpufreq_frequency_table_put_attr(policy->cpu);
restore_original_config();
/* Allow userspace to control CPU via /dev/toshiba again */
tosh_cpufreq_in_control = 0;
return 0;
}
static struct freq_attr* toshiba_freq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
static struct cpufreq_driver toshiba_freq_driver = {
.get = toshiba_freq_get_cpu_frequency,
.verify = toshiba_freq_verify,
.target = toshiba_freq_target,
.init = toshiba_freq_cpu_init,
.exit = toshiba_freq_cpu_exit,
.name = "toshiba_freq",
.owner = THIS_MODULE,
.attr = toshiba_freq_attr,
};
static int __init toshiba_freq_init(void)
{
char buf[128];
/* Save the original state */
if (tosh_scihci_get(0, SCI_BATTERY_SAVE, &original_battsave) ||
tosh_scihci_get(0, SCI_PROCESSING, &original_cpustate) ||
tosh_scihci_get(0, SCI_CPU_CACHE, &original_cache) ||
tosh_scihci_get(HCI_GET, HCI_FAN, &original_fan) ||
tosh_scihci_get(0, SCI_LCD_BRIGHTNESS, &original_brightness))
return -ENODEV;
/* Note: At least some ACPI machines do not allow the SMI handler to
* modify the CPU frequency. Here, we will read all the settings we
* are interested in and attempt to set their values, as a test that we
* are actually in control of the hardware. */
/* First the laptop must be put in the "user settings" battery
* save mode; otherwise the SMI handler rejects software requests to
* change CPU speed. */
if (tosh_scihci_set(0, SCI_BATTERY_SAVE, SCI_USER_SETTINGS)) {
restore_original_config();
return -ENODEV;
}
/* CPU state */
if (tosh_scihci_set(0, SCI_PROCESSING, original_cpustate)) {
restore_original_config();
return -ENODEV;
}
/* CPU cache */
if (control_cpucache) {
if (tosh_scihci_set(0, SCI_CPU_CACHE, original_cache)) {
restore_original_config();
return -ENODEV;
}
}
/* Fan */
if (control_fan) {
if (tosh_scihci_set(HCI_SET, HCI_FAN, original_fan)) {
restore_original_config();
return -ENODEV;
}
}
/* Display brightness */
if (control_lcd) {
if (tosh_scihci_set(0, SCI_LCD_BRIGHTNESS, original_brightness)) {
restore_original_config();
return -ENODEV;
}
}
/* Now that we know we can control all the appropriate settings,
* we can continue */
/* Now we need to obtain the nominal CPU speed for cpufreq to use.
*
* Possible methods: firmware, TSC, cpu_khz, user
* We don't know how to do it via firmware.
* cpu_khz is variable and thus unreliable.
* We thus try timing it with the TSC if available, and otherwise
* rely on the user to supply the speed.
*/
if (user_mhz < 0) {
/* Use TSC to estimate CPU speed */
u32 count, count2, lapsed_usec;
struct timeval tv, tv2;
int i;
if (!cpu_has_tsc) {
printk(DRIVER_NAME": 'mhz' option is required for systems without TSC\n");
restore_original_config();
return -EINVAL;
}
/* Place CPU into 'fast' state (max speed) */
if (tosh_scihci_set(0, SCI_PROCESSING, SCI_HIGH)) {
restore_original_config();
return -ENODEV;
}
/* According to RDTSCPM1.HTM, make 3 pre-runs to
* prime the instruction cache, and disable all
* pending speculations prior to RDTSC */
for (i = 0; i < 4; i++) {
local_irq_disable();
do_gettimeofday(&tv);
/* If core supports CPUID, then it may support
* speculative execution which should be evaded
* for accurate RDTSC timing */
if (boot_cpu_data.cpuid_level != -1)
sync_core();
count = get_cycles();
local_irq_enable();
msleep_interruptible(1);
local_irq_disable();
do_gettimeofday(&tv2);
if (boot_cpu_data.cpuid_level != -1)
sync_core();
count2 = get_cycles();
local_irq_enable();
}
if (tosh_scihci_set(0, SCI_PROCESSING, original_cpustate)) {
restore_original_config();
return -ENODEV;
}
lapsed_usec = 1000000*(tv2.tv_sec - tv.tv_sec) + (tv2.tv_usec - tv.tv_usec);
nominal_khz = (count2 - count) / lapsed_usec; /* cycles / us = MHz */
nominal_khz *= 1000; /* cycles / ms = kHz */
}
else
nominal_khz = user_mhz * 1000;
sprintf(buf, DRIVER_NAME": Managing CPU (nominal %d MHz)", nominal_khz / 1000);
if (control_cpucache)
strcat(buf, ", L2 cache");
if (control_fan)
strcat(buf, ", system fan");
if (control_lcd)
strcat(buf, ", LCD");
printk("%s\n", buf);
current_cpustate = original_cpustate;
return cpufreq_register_driver(&toshiba_freq_driver);
}
static void __exit toshiba_freq_exit(void)
{
cpufreq_unregister_driver(&toshiba_freq_driver);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ryan Underwood <nemesis@icequake.net>");
MODULE_DESCRIPTION("cpufreq driver for Toshiba non-Speedstep (SCI) laptops");
module_init(toshiba_freq_init);
module_exit(toshiba_freq_exit);
[-- Attachment #3: Type: text/plain, Size: 147 bytes --]
_______________________________________________
Cpufreq mailing list
Cpufreq@lists.linux.org.uk
http://lists.linux.org.uk/mailman/listinfo/cpufreq
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: writing a cpufreq driver 2006-09-21 18:48 writing a cpufreq driver Ryan Underwood @ 2006-09-21 19:31 ` Dave Jones 2006-09-21 19:38 ` Langsdorf, Mark 2006-09-21 20:08 ` Ryan Underwood 2006-09-22 15:39 ` Bruno Ducrot 1 sibling, 2 replies; 29+ messages in thread From: Dave Jones @ 2006-09-21 19:31 UTC (permalink / raw) To: nemesis; +Cc: Cpufreq On Thu, Sep 21, 2006 at 01:48:33PM -0500, Ryan Underwood wrote: > > I wrote a cpufreq target driver for older Toshiba laptops. It uses SMM > to change between a "fast" and a "slow" processing speed. I have two > remaining bugs. Any comments would be appreciated. > > 1. The first time cpufreq changes speed, I get the whole "Losing some > ticks... checking if CPU frequency changed." then eventually "Losing too > many ticks!" and timer switches to PIT. This does not happen when I use > the /dev/toshiba driver to change speeds from userspace. Not sure what > is going on here... SMI handler latency is between 6 and 7 ms. Is loops_per_jiffy being correctly scaled on a speed transition? Hmm, powernow-k7.c seems to be the only driver that's calling recalibrate_cpu_khz() > 2. The current CPU frequency is stored in NVRAM by the SMI handler. Wow, that's umm, crap :-} > Unfortunately, this means if cpufreq throttles the CPU and the system is > then rebooted, the boot process is exceedingly slow. Is there some sane > way to hook into the shutdown process to restore the appropriate values, > or is this something I have to live with? See register_reboot_notifier() Dave ^ permalink raw reply [flat|nested] 29+ messages in thread
* RE: writing a cpufreq driver 2006-09-21 19:31 ` Dave Jones @ 2006-09-21 19:38 ` Langsdorf, Mark 2006-09-21 19:47 ` Dave Jones 2006-09-21 20:08 ` Ryan Underwood 1 sibling, 1 reply; 29+ messages in thread From: Langsdorf, Mark @ 2006-09-21 19:38 UTC (permalink / raw) To: Dave Jones, nemesis; +Cc: Cpufreq > > 1. The first time cpufreq changes speed, I get the whole > "Losing some > > ticks... checking if CPU frequency changed." then > eventually "Losing too > > many ticks!" and timer switches to PIT. This does not > happen when I use > > the /dev/toshiba driver to change speeds from userspace. > Not sure what > > is going on here... SMI handler latency is between 6 and 7 ms. > > Is loops_per_jiffy being correctly scaled on a speed transition? > Hmm, powernow-k7.c seems to be the only driver that's calling > recalibrate_cpu_khz() Do drivers need to be doing that? I would have thought the time could would do it after receiving the notification. If not, I'll patch. -Mark Langsdorf AMD, Inc. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 19:38 ` Langsdorf, Mark @ 2006-09-21 19:47 ` Dave Jones 2006-09-22 15:44 ` Bruno Ducrot 0 siblings, 1 reply; 29+ messages in thread From: Dave Jones @ 2006-09-21 19:47 UTC (permalink / raw) To: Langsdorf, Mark; +Cc: Cpufreq, nemesis On Thu, Sep 21, 2006 at 02:38:22PM -0500, Langsdorf, Mark wrote: > > > 1. The first time cpufreq changes speed, I get the whole > > "Losing some > > > ticks... checking if CPU frequency changed." then > > eventually "Losing too > > > many ticks!" and timer switches to PIT. This does not > > happen when I use > > > the /dev/toshiba driver to change speeds from userspace. > > Not sure what > > > is going on here... SMI handler latency is between 6 and 7 ms. > > > > Is loops_per_jiffy being correctly scaled on a speed transition? > > Hmm, powernow-k7.c seems to be the only driver that's calling > > recalibrate_cpu_khz() > > Do drivers need to be doing that? I would have thought the > time could would do it after receiving the notification. Looking at it again.. cpufreq_notify_transition() is calling adjust_jiffies() which should be doing the same thing, so we should be good to go. It looks like feasible that recalibrate_cpu_khz() could actually be killed off. Dave ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 19:47 ` Dave Jones @ 2006-09-22 15:44 ` Bruno Ducrot 2006-09-22 15:49 ` Dave Jones 0 siblings, 1 reply; 29+ messages in thread From: Bruno Ducrot @ 2006-09-22 15:44 UTC (permalink / raw) To: Dave Jones; +Cc: Cpufreq, nemesis On Thu, Sep 21, 2006 at 03:47:14PM -0400, Dave Jones wrote: > On Thu, Sep 21, 2006 at 02:38:22PM -0500, Langsdorf, Mark wrote: > > > > 1. The first time cpufreq changes speed, I get the whole > > > "Losing some > > > > ticks... checking if CPU frequency changed." then > > > eventually "Losing too > > > > many ticks!" and timer switches to PIT. This does not > > > happen when I use > > > > the /dev/toshiba driver to change speeds from userspace. > > > Not sure what > > > > is going on here... SMI handler latency is between 6 and 7 ms. > > > > > > Is loops_per_jiffy being correctly scaled on a speed transition? > > > Hmm, powernow-k7.c seems to be the only driver that's calling > > > recalibrate_cpu_khz() > > > > Do drivers need to be doing that? I would have thought the > > time could would do it after receiving the notification. > > Looking at it again.. > cpufreq_notify_transition() is calling adjust_jiffies() > which should be doing the same thing, so we should be good to go. > > It looks like feasible that recalibrate_cpu_khz() could actually > be killed off. It's called only at init time because cpu_khz is not reliable on some platform due to braindamaged BIOS that switch frequency of the K7 onto the SMM handler when ACPI enable performance control, breaking AMD recommandation at the same time BTW. -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 15:44 ` Bruno Ducrot @ 2006-09-22 15:49 ` Dave Jones 0 siblings, 0 replies; 29+ messages in thread From: Dave Jones @ 2006-09-22 15:49 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Cpufreq, nemesis On Fri, Sep 22, 2006 at 05:44:48PM +0200, Bruno Ducrot wrote: > > Looking at it again.. > > cpufreq_notify_transition() is calling adjust_jiffies() > > which should be doing the same thing, so we should be good to go. > > > > It looks like feasible that recalibrate_cpu_khz() could actually > > be killed off. > > It's called only at init time because cpu_khz is not > reliable on some platform due to braindamaged BIOS > that switch frequency of the K7 onto the SMM handler > when ACPI enable performance control, breaking AMD > recommandation at the same time BTW. Ahh. That deserves a comment. Another alternative would be to do a transition on startup, which would end up adjusting it through the notifiers. Dave ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 19:31 ` Dave Jones 2006-09-21 19:38 ` Langsdorf, Mark @ 2006-09-21 20:08 ` Ryan Underwood 2006-09-21 20:44 ` Dave Jones 1 sibling, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-21 20:08 UTC (permalink / raw) To: Dave Jones; +Cc: Cpufreq, nemesis On Thu, Sep 21, 2006 at 03:31:41PM -0400, Dave Jones wrote: > > > > 1. The first time cpufreq changes speed, I get the whole "Losing some > > ticks... checking if CPU frequency changed." then eventually "Losing too > > many ticks!" and timer switches to PIT. This does not happen when I use > > the /dev/toshiba driver to change speeds from userspace. Not sure what > > is going on here... SMI handler latency is between 6 and 7 ms. > > Is loops_per_jiffy being correctly scaled on a speed transition? No, because only the firmware knows what the real CPU speeds are. How would I deal with this? > > 2. The current CPU frequency is stored in NVRAM by the SMI handler. > > Wow, that's umm, crap :-} Yup > > Unfortunately, this means if cpufreq throttles the CPU and the system is > > then rebooted, the boot process is exceedingly slow. Is there some sane > > way to hook into the shutdown process to restore the appropriate values, > > or is this something I have to live with? > > See register_reboot_notifier() That should do it. Thanks! -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 20:08 ` Ryan Underwood @ 2006-09-21 20:44 ` Dave Jones 2006-09-21 21:03 ` Ryan Underwood 0 siblings, 1 reply; 29+ messages in thread From: Dave Jones @ 2006-09-21 20:44 UTC (permalink / raw) To: Ryan Underwood; +Cc: Cpufreq On Thu, Sep 21, 2006 at 03:08:51PM -0500, Ryan Underwood wrote: > > On Thu, Sep 21, 2006 at 03:31:41PM -0400, Dave Jones wrote: > > > > > > 1. The first time cpufreq changes speed, I get the whole "Losing some > > > ticks... checking if CPU frequency changed." then eventually "Losing too > > > many ticks!" and timer switches to PIT. This does not happen when I use > > > the /dev/toshiba driver to change speeds from userspace. Not sure what > > > is going on here... SMI handler latency is between 6 and 7 ms. > > > > Is loops_per_jiffy being correctly scaled on a speed transition? > > No, because only the firmware knows what the real CPU speeds are. How > would I deal with this? Actually, if your driver is correctly using cpufreq_notify_transition() it should be doing this automagically for you. If you turn on debugging with cpufreq.debug=7 , you should see lines of the form. scaling loops_per_jiffy to %lu for frequency %u kHz\n Dave ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 20:44 ` Dave Jones @ 2006-09-21 21:03 ` Ryan Underwood 2006-09-21 21:13 ` Dave Jones 0 siblings, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-21 21:03 UTC (permalink / raw) To: Dave Jones; +Cc: Cpufreq [-- Attachment #1: Type: text/plain, Size: 534 bytes --] On Thu, Sep 21, 2006 at 04:44:02PM -0400, Dave Jones wrote: > > > > No, because only the firmware knows what the real CPU speeds are. How > > would I deal with this? > > Actually, if your driver is correctly using cpufreq_notify_transition() > it should be doing this automagically for you. If you turn on debugging with > cpufreq.debug=7 , you should see lines of the form. > > scaling loops_per_jiffy to %lu for frequency %u kHz\n I don't see this, here's the dmesg (2.6.16.28) -- Ryan Underwood, <nemesis@icequake.net> [-- Attachment #2: dmesg --] [-- Type: text/plain, Size: 15469 bytes --] 0000:00:04.0 got res [18040000:18040fff] bus [18040000:18040fff] flags 200 for BAR 0 of 0000:00:02.0 PCI: moved device 0000:00:02.0 resource 0 (200) to 18040000 got res [18041000:18041fff] bus [18041000:18041fff] flags 200 for BAR 0 of 0000:00:02.1 PCI: moved device 0000:00:02.1 resource 0 (200) to 18041000 PCI: Bus 1, cardbus bridge: 0000:00:02.0 IO window: 00001000-000010ff IO window: 00001400-000014ff PREFETCH window: 10000000-11ffffff MEM window: 12000000-13ffffff PCI: Bus 5, cardbus bridge: 0000:00:02.1 IO window: 00001800-000018ff IO window: 00001c00-00001cff PREFETCH window: 14000000-15ffffff MEM window: 16000000-17ffffff PCI: Enabling device 0000:00:02.0 (0004 -> 0007) PCI: Setting latency timer of device 0000:00:02.0 to 64 PCI: Enabling device 0000:00:02.1 (0004 -> 0007) PCI: Setting latency timer of device 0000:00:02.1 to 64 VFS: Disk quotas dquot_6.5.1 Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) Initializing Cryptographic API io scheduler noop registered io scheduler deadline registered (default) PCI: Calling quirk c01ce320 for 0000:00:00.0 PCI: Calling quirk c02052c9 for 0000:00:00.0 PCI: Calling quirk c01ce320 for 0000:00:02.0 PCI: Calling quirk c02052c9 for 0000:00:02.0 PCI: Calling quirk c01ce320 for 0000:00:02.1 PCI: Calling quirk c02052c9 for 0000:00:02.1 PCI: Calling quirk c01ce320 for 0000:00:04.0 PCI: Calling quirk c02052c9 for 0000:00:04.0 isapnp: Scanning for PnP cards... isapnp: No Plug & Play device found pnp: the driver 'i8042 kbd' has been registered pnp: match found with the PnP device '00:07' and the driver 'i8042 kbd' pnp: the driver 'i8042 aux' has been registered pnp: match found with the PnP device '00:08' and the driver 'i8042 aux' PNP: PS/2 Controller [PNP0303,PNP0f13] at 0x60,0x64 irq 1,12 serio: i8042 AUX port at 0x60,0x64 irq 12 serio: i8042 KBD port at 0x60,0x64 irq 1 Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A pnp: the driver 'serial' has been registered pnp: match found with the PnP device '00:0e' and the driver 'serial' 00:0e: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A pnp: match found with the PnP device '00:15' and the driver 'serial' 00:15: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A RAMDISK driver initialized: 16 RAM disks of 8192K size 1024 blocksize Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2 ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx Probing IDE interface ide0... hda: FUJITSU MHH2048AT, ATA DISK drive Probing IDE interface ide1... hdc: TOSHIBA CD-ROM XM-1502BN, ATAPI CD/DVD-ROM drive ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 ide1 at 0x170-0x177,0x376 on irq 15 hda: max request size: 128KiB hda: 9514260 sectors (4871 MB) w/512KiB Cache, CHS=10068/15/63 hda: cache flushes not supported hda: hda1 hda2 EISA: Probing bus 0 at eisa.0 Cannot allocate resource for EISA slot 1 EISA: Detected 0 cards. NET: Registered protocol family 2 input: AT Translated Set 2 keyboard as /class/input/input0 IP route cache hash table entries: 2048 (order: 1, 8192 bytes) TCP established hash table entries: 8192 (order: 3, 32768 bytes) TCP bind hash table entries: 8192 (order: 3, 32768 bytes) TCP: Hash tables configured (established 8192 bind 8192) TCP reno registered TCP bic registered Using IPI Shortcut mode kjournald starting. Commit interval 5 seconds EXT3-fs: mounted filesystem with ordered data mode. VFS: Mounted root (ext3 filesystem) readonly. Freeing unused kernel memory: 196k freed Write protecting the kernel read-only data: 236k NET: Registered protocol family 1 hdc: ATAPI 10X CD-ROM drive, 128kB Cache Uniform CD-ROM driver Revision: 3.20 Floppy drive(s): fd0 is 1.44M FDC 0 is an 8272A input: PS/2 Generic Mouse as /class/input/input1 irda_init() NET: Registered protocol family 23 Real Time Clock Driver v1.12ac input: PC Speaker as /class/input/input2 pnp: the driver 'parport_pc' has been registered pnp: match found with the PnP device '00:10' and the driver 'parport_pc' parport: PnPBIOS parport detected. parport0: PC-style at 0x378 (0x778), irq 7, dma 3 [PCSPP,TRISTATE,COMPAT,ECP,DMA] pnp: the driver 'cs4232-pnpbios' has been registered pnp: match found with the PnP device '00:17' and the driver 'cs4232-pnpbios' ALSA sound/isa/cs423x/cs4236.c:293: CS4232 WSS PnP manual resources are invalid, using auto config CS4232 WSS PnP configure failed for WSS (out of resources?) PnP BIOS detection failed for CS4232 pnp: Failed to disable device 00:17. cs4232-pnpbios: probe of 00:17 failed with error -16 pnp: the driver 'cs4232_isapnp' has been registered CS4232 soundcard not found or device busy pnp: the driver 'cs4232_isapnp' has been unregistered pnp: the driver 'cs4232-pnpbios' has been unregistered Yenta: CardBus bridge found at 0000:00:02.0 [0000:0000] Yenta: ISA IRQ mask 0x0000, PCI irq 11 Socket status: 30000010 Yenta: CardBus bridge found at 0000:00:02.1 [0000:0000] Yenta: ISA IRQ mask 0x0000, PCI irq 11 Socket status: 30000006 pccard: PCMCIA card inserted into slot 0 pnp: the driver 'cs4232-pnpbios' has been registered pnp: match found with the PnP device '00:17' and the driver 'cs4232-pnpbios' ALSA sound/isa/cs423x/cs4236.c:293: CS4232 WSS PnP manual resources are invalid, using auto config CS4232 WSS PnP configure failed for WSS (out of resources?) PnP BIOS detection failed for CS4232 pnp: Failed to disable device 00:17. cs4232-pnpbios: probe of 00:17 failed with error -16 pnp: the driver 'cs4232_isapnp' has been registered CS4232 soundcard not found or device busy pnp: the driver 'cs4232_isapnp' has been unregistered pnp: the driver 'cs4232-pnpbios' has been unregistered ts: Compaq touchscreen protocol output mice: PS/2 mouse device common for all mice cs: IO port probe 0x100-0x4ff: excluding 0x120-0x127 0x220-0x22f 0x388-0x38f 0x480-0x48f 0x4d0-0x4d7 cs: IO port probe 0x800-0x8ff: clean. cs: IO port probe 0xc00-0xcff: clean. cs: IO port probe 0x1000-0x10ff: clean. cs: IO port probe 0x1400-0x14ff: clean. cs: IO port probe 0x1800-0x18ff: clean. cs: IO port probe 0x100-0x4ff: excluding 0x120-0x127 0x220-0x22f 0x388-0x38f 0x480-0x48f 0x4d0-0x4d7 cs: IO port probe 0x800-0x8ff: clean. cs: IO port probe 0xc00-0xcff: clean. cs: IO port probe 0x1000-0x10ff: clean. cs: IO port probe 0x1400-0x14ff: clean. cs: IO port probe 0x1800-0x18ff: clean. cs: IO port probe 0x1c00-0x1cff: clean. cs: IO port probe 0x1c00-0x1cff: clean. cs: memory probe 0xa0000000-0xa0ffffff: clean. pcmcia: registering new device pcmcia0.0 pcmcia: registering new device pcmcia0.1 0.1: ttyS2 at I/O 0x3e8 (irq = 11) is a 16550A eth0: NE2000 Compatible: io 0x300, irq 11, mem 0xca140000, auto xcvr, hw_addr 00:04:AC:84:59:C0 Adding 460204k swap on /dev/hda2. Priority:-1 extents:1 across:460204k EXT3 FS on hda1, internal journal Toshiba System Managment Mode driver v1.11 26/9/2001 apm: BIOS version 1.2 Flags 0x02 (Driver version 1.16ac) pnp: the driver 'cs4232-pnpbios' has been registered pnp: match found with the PnP device '00:17' and the driver 'cs4232-pnpbios' ALSA sound/isa/cs423x/cs4236.c:293: CS4232 WSS PnP manual resources are invalid, using auto config CS4232 WSS PnP configure failed for WSS (out of resources?) PnP BIOS detection failed for CS4232 pnp: Failed to disable device 00:17. cs4232-pnpbios: probe of 00:17 failed with error -16 pnp: the driver 'cs4232_isapnp' has been registered CS4232 soundcard not found or device busy pnp: the driver 'cs4232_isapnp' has been unregistered pnp: the driver 'cs4232-pnpbios' has been unregistered register_blkdev: cannot get major 31 for mtdblock Unable to register mtdblock block device on major 31: -16 slram: devname=ram_uncached, devstart=0x4000000, devlength=0x5000000 slram: ioremap failed NET: Registered protocol family 17 openafs: module license 'http://www.openafs.org/dl/license10.html' taints kernel. Found system call table at 0xc02624a0 (pattern scan) Address 0xc02624a0 is not writable. System call hooks will not be installed; proceeding anyway Starting AFS cache scan...found 2532 non-empty cache files (25%). NET: Registered protocol family 4 pccard: card ejected from slot 0 pccard: PCMCIA card inserted into slot 0 pcmcia: registering new device pcmcia0.0 eth0: NE2000 Compatible: io 0x300, irq 11, mem 0xca140000, auto xcvr, hw_addr 00:04:AC:84:59:C0 pcmcia: registering new device pcmcia0.1 0.1: ttyS2 at I/O 0x3e8 (irq = 11) is a 16550A NET: Registered protocol family 10 lo: Disabled Privacy Extensions IPv6 over IPv4 tunneling driver sit0: Disabled Privacy Extensions eth0: no IPv6 routers present toshiba_freq: Managing CPU (nominal 120 MHz), L2 cache, system fan Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing too many ticks! TSC cannot be used as a timesource. Possible reasons for this are: You're running with Speedstep, You don't have DMA enabled for your hard disk (see hdparm), Incorrect TSC synchronization on an SMP system (see dmesg). Falling back to a sane timesource now. Losing some ticks... checking if CPU frequency changed. cpufreq-core: unregistering driver toshiba_freq cpufreq-core: unregistering CPU 0 cpufreq-core: __cpufreq_governor for CPU 0, event 2 cpufreq-core: last reference is dropped cpufreq-core: waiting for dropping of refcount cpufreq-core: wait complete freq-table: clearing show_table for cpu 0 toshiba_freq: Managing CPU (nominal 120 MHz), L2 cache, system fan cpufreq-core: trying to register driver toshiba_freq cpufreq-core: adding CPU 0 freq-table: table entry 0: 60000 kHz, 0 index freq-table: table entry 1: 120000 kHz, 1 index freq-table: setting show_table for cpu 0 to ca449908 cpufreq-core: setting new policy for CPU 0: 60000 - 120000 kHz freq-table: request for verification of policy (60000 - 120000 kHz) for cpu 0 freq-table: verification lead to (60000 - 120000 kHz) for cpu 0 freq-table: request for verification of policy (60000 - 120000 kHz) for cpu 0 freq-table: verification lead to (60000 - 120000 kHz) for cpu 0 cpufreq-core: new min and max freqs are 60000 - 120000 kHz cpufreq-core: governor switch cpufreq-core: __cpufreq_governor for CPU 0, event 1 performance: setting to 120000 kHz because of event 1 cpufreq-core: target for CPU 0: 120000 kHz, relation 1 freq-table: request for target 120000 kHz (relation: 1) for cpu 0 freq-table: target is 1 (120000 kHz, 1) cpufreq-core: notification 0 of frequency transition to 120000 kHz toshiba_freq: toshiba_freq: attempting to set frequency to 120000 kHz toshiba_freq: toshiba_freq: SMM took 832684 cycles cpufreq-core: notification 1 of frequency transition to 120000 kHz cpufreq-core: governor: change or update limits cpufreq-core: __cpufreq_governor for CPU 0, event 3 performance: setting to 120000 kHz because of event 3 cpufreq-core: target for CPU 0: 120000 kHz, relation 1 freq-table: request for target 120000 kHz (relation: 1) for cpu 0 freq-table: target is 1 (120000 kHz, 1) cpufreq-core: notification 0 of frequency transition to 120000 kHz toshiba_freq: toshiba_freq: attempting to set frequency to 120000 kHz toshiba_freq: toshiba_freq: SMM took 778574 cycles cpufreq-core: notification 1 of frequency transition to 120000 kHz cpufreq-core: initialization complete cpufreq-core: driver toshiba_freq up and running [-- Attachment #3: Type: text/plain, Size: 147 bytes --] _______________________________________________ Cpufreq mailing list Cpufreq@lists.linux.org.uk http://lists.linux.org.uk/mailman/listinfo/cpufreq ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 21:03 ` Ryan Underwood @ 2006-09-21 21:13 ` Dave Jones 2006-09-22 14:13 ` Ryan Underwood 0 siblings, 1 reply; 29+ messages in thread From: Dave Jones @ 2006-09-21 21:13 UTC (permalink / raw) To: Ryan Underwood; +Cc: Cpufreq On Thu, Sep 21, 2006 at 04:03:29PM -0500, Ryan Underwood wrote: > > On Thu, Sep 21, 2006 at 04:44:02PM -0400, Dave Jones wrote: > > > > > > No, because only the firmware knows what the real CPU speeds are. How > > > would I deal with this? > > > > Actually, if your driver is correctly using cpufreq_notify_transition() > > it should be doing this automagically for you. If you turn on debugging with > > cpufreq.debug=7 , you should see lines of the form. > > > > scaling loops_per_jiffy to %lu for frequency %u kHz\n > > I don't see this, here's the dmesg (2.6.16.28) Pointer to the driver source ? Dave ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 21:13 ` Dave Jones @ 2006-09-22 14:13 ` Ryan Underwood 2006-09-22 14:39 ` Ryan Underwood 0 siblings, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-22 14:13 UTC (permalink / raw) To: Dave Jones; +Cc: Cpufreq, Ryan Underwood [-- Attachment #1: Type: text/plain, Size: 693 bytes --] On Thu, Sep 21, 2006 at 05:13:43PM -0400, Dave Jones wrote: > > Pointer to the driver source ? Sorry, I had email problems yesterday, let me know if you don't get this email ;) dmesg + driver source attached I have a question, how critical is it that I have exactly the correct CPU MHz for the scaling to work properly? Unfortunately, for the slow speed there is no way for me to know what it actually is on a particular system due to limitations of the firmware, so the best I could do is a RDTSC timing to try to figure it out. I wonder if skew between the actual CPU speed and what cpufreq thinks it is would be the source of the problem. -- Ryan Underwood, <nemesis@icequake.net> [-- Attachment #2: toshiba_freq.c --] [-- Type: text/x-csrc, Size: 12925 bytes --] /* * toshiba_freq.c: cpufreq driver for Toshiba SCI (non-Speedstep) laptops * * Copyright (C) 2006 Ryan Underwood <nemesis@icequake.net> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Based on sc520_freq.c * * 2006-09-11: - initial revision */ /* NOTE: currently this should drag in toshiba.ko which checks for the * appropriate hardware in its init function. Things will be different when * ACPI instead of the SMM driver is used as the SCI access method. * * This module should respect the user's firmware configuration prior to * loading it and preserve it always when the module encounters an error, * is unloaded, or the system is rebooted. Unfortunately, there is no way * to handle the case of a SysRq reboot. */ /* FIXME: Fan and LCD brightness are variable on some systems */ /* FIXME: TSC timer needs recalibration, why isn't this an issue with /dev/toshiba? */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/timex.h> #include <linux/delay.h> #include <linux/reboot.h> #include <linux/cpufreq.h> #include <linux/toshiba.h> #define DRIVER_NAME "toshiba_freq" #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg) static u32 original_battsave; static u32 original_cpustate; static u32 original_cache; static u32 original_brightness; static u32 original_fan; /* Store this locally to avoid a SMM round trip to obtain it */ static u32 current_cpustate; /* The operating speed of the CPU when in 'fast' mode */ static int nominal_khz; /* The maximum SMI interrupt latency we have encountered */ static int max_smm_latency = 7000000; /* Start with 7ms */ /* Has an SCI error occurred in the past? */ static int sci_halt; static int control_cpucache = 1; static int control_fan = 1; static int control_lcd; /* User-supplied nominal MHz rating */ static int user_mhz = -1; module_param_named(cpucache, control_cpucache, int, 1); MODULE_PARM_DESC(cpucache, "Allow CPUFreq to enable/disable CPU cache"); module_param_named(fan, control_fan, int, 1); MODULE_PARM_DESC(fan, "Allow CPUFreq to control the system fan"); module_param_named(lcd, control_lcd, int, 0); MODULE_PARM_DESC(lcd, "Allow CPUFreq to control LCD brightness"); module_param_named(mhz, user_mhz, int, -1); MODULE_PARM_DESC(mhz, "MHz rating of CPU (required for pre-Pentium)"); /* Index corresponds to the SCI CPU speed state (0 or 1) */ static struct cpufreq_frequency_table toshiba_freq_table[] = { {0, 0}, /* slow (low) */ {1, 0}, /* fast (high) */ {0, CPUFREQ_TABLE_END}, }; static void restore_original_config(void) { /* Attempt to unconditionally reset the original values */ if (control_fan) tosh_scihci_set(HCI_SET, HCI_FAN, original_fan); if (control_lcd) tosh_scihci_set(0, SCI_LCD_BRIGHTNESS, original_brightness); if (control_cpucache) tosh_scihci_set(0, SCI_CPU_CACHE, original_cache); tosh_scihci_set(0, SCI_PROCESSING, original_cpustate); tosh_scihci_set(0, SCI_BATTERY_SAVE, original_battsave); } static int toshiba_freq_notify_reboot(struct notifier_block *this, unsigned long code, void *x) { /* We don't care what the code is, do this always. */ restore_original_config(); return NOTIFY_DONE; } static struct notifier_block toshiba_freq_notifier = { toshiba_freq_notify_reboot, NULL, 0 }; static unsigned int toshiba_freq_get_cpu_frequency(unsigned int cpu) { #if 0 unsigned int val; tosh_scihci_get(0, SCI_PROCESSING, &val); val &= 1; /* safety */ return toshiba_freq_table[val].frequency; #else /* It is okay to cache this, as long as userland is * prevented from messing with the current state via * /dev/toshiba. */ return toshiba_freq_table[current_cpustate].frequency; #endif } static void tosh_scihci_set_error(unsigned int hci, unsigned int cmd, unsigned int arg) { int err; int transition_usecs; struct timeval tv, tv2; if (sci_halt) return; do_gettimeofday(&tv); err = tosh_scihci_set(hci, cmd, arg); do_gettimeofday(&tv2); transition_usecs = 1000000*(tv2.tv_sec - tv.tv_sec) + (tv2.tv_usec - tv.tv_usec); if (transition_usecs*1000 > max_smm_latency) { /* latency is in ns */ dprintk(DRIVER_NAME": transition latency increased from %d to %d ns\n", max_smm_latency, transition_usecs*1000); max_smm_latency = transition_usecs * 1000; } if (err) { sci_halt = 1; /* Attempt to restore the original config, so i.e. the * processor is not at high speed while the fan is not on, * or some other inconsistent state. */ restore_original_config(); /* We will do nothing more now */ printk(DRIVER_NAME": SCI error condition encountered, giving up.\n"); tosh_cpufreq_in_control = 0; } } static void toshiba_freq_set_cpu_state (unsigned int state) { struct cpufreq_freqs freqs; freqs.old = toshiba_freq_get_cpu_frequency(0); freqs.new = toshiba_freq_table[state].frequency; freqs.cpu = 0; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); dprintk(DRIVER_NAME": attempting to set frequency to %i kHz\n", toshiba_freq_table[state].frequency); if (state == 0) { /* slow */ if (control_fan) tosh_scihci_set_error(HCI_SET, HCI_FAN, HCI_DISABLE); if (control_lcd) tosh_scihci_set_error(0, SCI_LCD_BRIGHTNESS, SCI_SEMI_BRIGHT); if (control_cpucache) tosh_scihci_set_error(0, SCI_CPU_CACHE, SCI_OFF); tosh_scihci_set_error(0, SCI_PROCESSING, SCI_LOW); } else { /* fast */ if (control_fan) tosh_scihci_set_error(HCI_SET, HCI_FAN, HCI_ENABLE); if (control_lcd) tosh_scihci_set_error(0, SCI_LCD_BRIGHTNESS, SCI_BRIGHT); if (control_cpucache) tosh_scihci_set_error(0, SCI_CPU_CACHE, SCI_ON); #if 0 tosh_scihci_set_error(0, SCI_PROCESSING, SCI_HIGH); #else { //Experimenting with SMM latency u32 low, low2; local_irq_disable(); sync_core(); low = get_cycles(); tosh_scihci_set_error(0, SCI_PROCESSING, SCI_HIGH); sync_core(); low2 = get_cycles(); local_irq_enable(); dprintk(DRIVER_NAME": SMM took %d cycles\n", low2-low); } #endif } current_cpustate = toshiba_freq_table[state].index; cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); }; static int toshiba_freq_verify (struct cpufreq_policy *policy) { return cpufreq_frequency_table_verify(policy, &toshiba_freq_table[0]); } static int toshiba_freq_target (struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { unsigned int newstate = 0; if (cpufreq_frequency_table_target(policy, toshiba_freq_table, target_freq, relation, &newstate)) return -EINVAL; toshiba_freq_set_cpu_state(newstate); policy->cpuinfo.transition_latency = max_smm_latency; return 0; } /* * Module init and exit code */ static int toshiba_freq_cpu_init(struct cpufreq_policy *policy) { int result; /* Make sure we don't leave the system in a bad state at reboot */ register_reboot_notifier(&toshiba_freq_notifier); /* Prevent userspace from using /dev/toshiba to frob the CPU speed */ tosh_cpufreq_in_control = 1; /* Fill out the frequency table (in KHz) for the two Toshiba SCI modes * "slow" and "fast". */ toshiba_freq_table[0].frequency = nominal_khz / 2; toshiba_freq_table[1].frequency = nominal_khz; /* cpuinfo and default policy values */ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = max_smm_latency; policy->cur = toshiba_freq_get_cpu_frequency(0); result = cpufreq_frequency_table_cpuinfo(policy, toshiba_freq_table); if (result) return (result); cpufreq_frequency_table_get_attr(toshiba_freq_table, policy->cpu); return 0; } static int toshiba_freq_cpu_exit(struct cpufreq_policy *policy) { cpufreq_frequency_table_put_attr(policy->cpu); restore_original_config(); unregister_reboot_notifier(&toshiba_freq_notifier); /* Allow userspace to control CPU via /dev/toshiba again */ tosh_cpufreq_in_control = 0; return 0; } static struct freq_attr* toshiba_freq_attr[] = { &cpufreq_freq_attr_scaling_available_freqs, NULL, }; static struct cpufreq_driver toshiba_freq_driver = { .get = toshiba_freq_get_cpu_frequency, .verify = toshiba_freq_verify, .target = toshiba_freq_target, .init = toshiba_freq_cpu_init, .exit = toshiba_freq_cpu_exit, .name = "toshiba_freq", .owner = THIS_MODULE, .attr = toshiba_freq_attr, }; static int __init toshiba_freq_init(void) { char buf[128]; /* Save the original state */ if (tosh_scihci_get(0, SCI_BATTERY_SAVE, &original_battsave) || tosh_scihci_get(0, SCI_PROCESSING, &original_cpustate) || tosh_scihci_get(0, SCI_CPU_CACHE, &original_cache) || tosh_scihci_get(HCI_GET, HCI_FAN, &original_fan) || tosh_scihci_get(0, SCI_LCD_BRIGHTNESS, &original_brightness)) return -ENODEV; /* Note: At least some ACPI machines do not allow the SMI handler to * modify the CPU frequency. Here, we will read all the settings we * are interested in and attempt to set their values, as a test that we * are actually in control of the hardware. */ /* First the laptop must be put in the "user settings" battery * save mode; otherwise the SMI handler rejects software requests to * change CPU speed. */ if (tosh_scihci_set(0, SCI_BATTERY_SAVE, SCI_USER_SETTINGS)) { restore_original_config(); return -ENODEV; } /* CPU state */ if (tosh_scihci_set(0, SCI_PROCESSING, original_cpustate)) { restore_original_config(); return -ENODEV; } /* CPU cache */ if (control_cpucache) { if (tosh_scihci_set(0, SCI_CPU_CACHE, original_cache)) { restore_original_config(); return -ENODEV; } } /* Fan */ if (control_fan) { if (tosh_scihci_set(HCI_SET, HCI_FAN, original_fan)) { restore_original_config(); return -ENODEV; } } /* Display brightness */ if (control_lcd) { if (tosh_scihci_set(0, SCI_LCD_BRIGHTNESS, original_brightness)) { restore_original_config(); return -ENODEV; } } /* Now that we know we can control all the appropriate settings, * we can continue */ /* Now we need to obtain the nominal CPU speed for cpufreq to use. * * Possible methods: firmware, TSC, cpu_khz, user * We don't know how to do it via firmware. * cpu_khz is variable and thus unreliable. * We thus try timing it with the TSC if available, and otherwise * rely on the user to supply the speed. */ if (user_mhz < 0) { /* Use TSC to estimate CPU speed */ u32 count, count2, lapsed_usec; struct timeval tv, tv2; int i; if (!cpu_has_tsc) { printk(DRIVER_NAME": 'mhz' option is required for systems without TSC\n"); restore_original_config(); return -EINVAL; } #if 0 /* Place CPU into 'fast' state (max speed) */ if (tosh_scihci_set(0, SCI_PROCESSING, SCI_LOW)) { restore_original_config(); return -ENODEV; } sync_core(); asm __volatile__ ( "mov %%cr0, %0" : "=r"(i) ); printk("cr0 low: %lx\n", i); #endif /* Place CPU into 'fast' state (max speed) */ if (tosh_scihci_set(0, SCI_PROCESSING, SCI_HIGH)) { restore_original_config(); return -ENODEV; } #if 0 sync_core(); asm __volatile__ ( "mov %%cr0, %0" : "=r"(i) ); printk("cr0 high: %lx\n", i); #endif /* According to RDTSCPM1.HTM, make 3 pre-runs to * prime the instruction cache, and disable all * pending speculations prior to RDTSC */ for (i = 0; i < 4; i++) { local_irq_disable(); do_gettimeofday(&tv); /* If core supports CPUID, then it may support * speculative execution which should be evaded * for accurate RDTSC timing */ if (boot_cpu_data.cpuid_level != -1) sync_core(); count = get_cycles(); local_irq_enable(); msleep_interruptible(1); local_irq_disable(); do_gettimeofday(&tv2); if (boot_cpu_data.cpuid_level != -1) sync_core(); count2 = get_cycles(); local_irq_enable(); } if (tosh_scihci_set(0, SCI_PROCESSING, original_cpustate)) { restore_original_config(); return -ENODEV; } lapsed_usec = 1000000*(tv2.tv_sec - tv.tv_sec) + (tv2.tv_usec - tv.tv_usec); nominal_khz = (count2 - count) / lapsed_usec; /* cycles / us = MHz */ nominal_khz *= 1000; /* cycles / ms = kHz */ } else nominal_khz = user_mhz * 1000; sprintf(buf, DRIVER_NAME": Managing CPU (nominal %d MHz)", nominal_khz / 1000); if (control_cpucache) strcat(buf, ", L2 cache"); if (control_fan) strcat(buf, ", system fan"); if (control_lcd) strcat(buf, ", LCD"); printk("%s\n", buf); current_cpustate = original_cpustate; return cpufreq_register_driver(&toshiba_freq_driver); } static void __exit toshiba_freq_exit(void) { cpufreq_unregister_driver(&toshiba_freq_driver); } MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ryan Underwood <nemesis@icequake.net>"); MODULE_DESCRIPTION("cpufreq driver for Toshiba non-Speedstep (SCI) laptops"); module_init(toshiba_freq_init); module_exit(toshiba_freq_exit); [-- Attachment #3: dmesg --] [-- Type: text/plain, Size: 15520 bytes --] protocol family 1 hdc: ATAPI 10X CD-ROM drive, 128kB Cache Uniform CD-ROM driver Revision: 3.20 input: PS/2 Generic Mouse as /class/input/input1 pnp: the driver 'parport_pc' has been registered pnp: match found with the PnP device '00:10' and the driver 'parport_pc' parport: PnPBIOS parport detected. parport0: PC-style at 0x378 (0x778), irq 7, dma 3 [PCSPP,TRISTATE,COMPAT,ECP,DMA] irda_init() NET: Registered protocol family 23 Real Time Clock Driver v1.12ac input: PC Speaker as /class/input/input2 Floppy drive(s): fd0 is 1.44M FDC 0 is an 8272A Yenta: CardBus bridge found at 0000:00:02.0 [0000:0000] Yenta: ISA IRQ mask 0x0000, PCI irq 11 Socket status: 30000010 Yenta: CardBus bridge found at 0000:00:02.1 [0000:0000] Yenta: ISA IRQ mask 0x0000, PCI irq 11 Socket status: 30000006 pccard: PCMCIA card inserted into slot 0 pnp: the driver 'cs4232-pnpbios' has been registered pnp: match found with the PnP device '00:17' and the driver 'cs4232-pnpbios' ALSA sound/isa/cs423x/cs4236.c:293: CS4232 WSS PnP manual resources are invalid, using auto config CS4232 WSS PnP configure failed for WSS (out of resources?) PnP BIOS detection failed for CS4232 pnp: Failed to disable device 00:17. cs4232-pnpbios: probe of 00:17 failed with error -16 pnp: the driver 'cs4232_isapnp' has been registered CS4232 soundcard not found or device busy pnp: the driver 'cs4232_isapnp' has been unregistered pnp: the driver 'cs4232-pnpbios' has been unregistered pnp: the driver 'cs4232-pnpbios' has been registered pnp: match found with the PnP device '00:17' and the driver 'cs4232-pnpbios' ALSA sound/isa/cs423x/cs4236.c:293: CS4232 WSS PnP manual resources are invalid, using auto config CS4232 WSS PnP configure failed for WSS (out of resources?) PnP BIOS detection failed for CS4232 pnp: Failed to disable device 00:17. cs4232-pnpbios: probe of 00:17 failed with error -16 pnp: the driver 'cs4232_isapnp' has been registered CS4232 soundcard not found or device busy pnp: the driver 'cs4232_isapnp' has been unregistered pnp: the driver 'cs4232-pnpbios' has been unregistered ts: Compaq touchscreen protocol output mice: PS/2 mouse device common for all mice cs: IO port probe 0x100-0x4ff: excluding 0x120-0x127 0x220-0x22f 0x388-0x38f 0x480-0x48f 0x4d0-0x4d7 cs: IO port probe 0x800-0x8ff: clean. cs: IO port probe 0xc00-0xcff: clean. cs: IO port probe 0x1000-0x10ff: clean. cs: IO port probe 0x1400-0x14ff: clean. cs: IO port probe 0x1800-0x18ff: clean. cs: IO port probe 0x1c00-0x1cff: clean. cs: memory probe 0xa0000000-0xa0ffffff: clean. pcmcia: registering new device pcmcia0.0 pcmcia: registering new device pcmcia0.1 cs: IO port probe 0x100-0x4ff: excluding 0x120-0x127 0x220-0x22f 0x388-0x38f 0x480-0x48f 0x4d0-0x4d7 cs: IO port probe 0x800-0x8ff: clean. cs: IO port probe 0xc00-0xcff: clean. cs: IO port probe 0x1000-0x10ff: clean. cs: IO port probe 0x1400-0x14ff: clean. cs: IO port probe 0x1800-0x18ff: clean. cs: IO port probe 0x1c00-0x1cff: clean. eth0: NE2000 Compatible: io 0x300, irq 11, mem 0xca128000, auto xcvr, hw_addr 00:04:AC:84:59:C0 0.1: ttyS2 at I/O 0x3e8 (irq = 11) is a 16550A Adding 460204k swap on /dev/hda2. Priority:-1 extents:1 across:460204k EXT3 FS on hda1, internal journal Toshiba System Managment Mode driver v1.11 26/9/2001 apm: BIOS version 1.2 Flags 0x02 (Driver version 1.16ac) pnp: the driver 'cs4232-pnpbios' has been registered pnp: match found with the PnP device '00:17' and the driver 'cs4232-pnpbios' ALSA sound/isa/cs423x/cs4236.c:293: CS4232 WSS PnP manual resources are invalid, using auto config CS4232 WSS PnP configure failed for WSS (out of resources?) PnP BIOS detection failed for CS4232 pnp: Failed to disable device 00:17. cs4232-pnpbios: probe of 00:17 failed with error -16 pnp: the driver 'cs4232_isapnp' has been registered CS4232 soundcard not found or device busy pnp: the driver 'cs4232_isapnp' has been unregistered pnp: the driver 'cs4232-pnpbios' has been unregistered register_blkdev: cannot get major 31 for mtdblock Unable to register mtdblock block device on major 31: -16 slram: devname=ram_uncached, devstart=0x4000000, devlength=0x5000000 slram: ioremap failed NET: Registered protocol family 17 openafs: module license 'http://www.openafs.org/dl/license10.html' taints kernel. Found system call table at 0xc02624a0 (pattern scan) Address 0xc02624a0 is not writable. System call hooks will not be installed; proceeding anyway Starting AFS cache scan...found 2532 non-empty cache files (25%). NET: Registered protocol family 4 pccard: card ejected from slot 0 pccard: PCMCIA card inserted into slot 0 pcmcia: registering new device pcmcia0.0 eth0: NE2000 Compatible: io 0x300, irq 11, mem 0xca128000, auto xcvr, hw_addr 00:04:AC:84:59:C0 pcmcia: registering new device pcmcia0.1 0.1: ttyS2 at I/O 0x3e8 (irq = 11) is a 16550A NET: Registered protocol family 10 lo: Disabled Privacy Extensions IPv6 over IPv4 tunneling driver sit0: Disabled Privacy Extensions eth0: no IPv6 routers present toshiba_freq: Managing CPU (nominal 120 MHz), L2 cache, system fan cpufreq-core: trying to register driver toshiba_freq cpufreq-core: adding CPU 0 freq-table: table entry 0: 60000 kHz, 0 index freq-table: table entry 1: 120000 kHz, 1 index freq-table: setting show_table for cpu 0 to ca449908 cpufreq-core: setting new policy for CPU 0: 60000 - 120000 kHz freq-table: request for verification of policy (60000 - 120000 kHz) for cpu 0 freq-table: verification lead to (60000 - 120000 kHz) for cpu 0 freq-table: request for verification of policy (60000 - 120000 kHz) for cpu 0 freq-table: verification lead to (60000 - 120000 kHz) for cpu 0 cpufreq-core: new min and max freqs are 60000 - 120000 kHz cpufreq-core: governor switch cpufreq-core: __cpufreq_governor for CPU 0, event 1 performance: setting to 120000 kHz because of event 1 cpufreq-core: target for CPU 0: 120000 kHz, relation 1 freq-table: request for target 120000 kHz (relation: 1) for cpu 0 freq-table: target is 1 (120000 kHz, 1) cpufreq-core: notification 0 of frequency transition to 120000 kHz cpufreq-core: saving 1203703 as reference value for loops_per_jiffy; freq is 120000 kHz toshiba_freq: toshiba_freq: attempting to set frequency to 120000 kHz toshiba_freq: toshiba_freq: SMM took 779732 cycles cpufreq-core: notification 1 of frequency transition to 120000 kHz cpufreq-core: governor: change or update limits cpufreq-core: __cpufreq_governor for CPU 0, event 3 performance: setting to 120000 kHz because of event 3 cpufreq-core: target for CPU 0: 120000 kHz, relation 1 freq-table: request for target 120000 kHz (relation: 1) for cpu 0 freq-table: target is 1 (120000 kHz, 1) cpufreq-core: notification 0 of frequency transition to 120000 kHz toshiba_freq: toshiba_freq: attempting to set frequency to 120000 kHz toshiba_freq: toshiba_freq: SMM took 811010 cycles cpufreq-core: notification 1 of frequency transition to 120000 kHz cpufreq-core: initialization complete cpufreq-core: driver toshiba_freq up and running cpufreq-core: setting new policy for CPU 0: 60000 - 120000 kHz freq-table: request for verification of policy (60000 - 120000 kHz) for cpu 0 freq-table: verification lead to (60000 - 120000 kHz) for cpu 0 freq-table: request for verification of policy (60000 - 120000 kHz) for cpu 0 freq-table: verification lead to (60000 - 120000 kHz) for cpu 0 cpufreq-core: new min and max freqs are 60000 - 120000 kHz cpufreq-core: governor switch cpufreq-core: __cpufreq_governor for CPU 0, event 2 cpufreq-core: __cpufreq_governor for CPU 0, event 1 cpufreq-core: governor: change or update limits cpufreq-core: __cpufreq_governor for CPU 0, event 3 cpufreq-core: target for CPU 0: 8571 kHz, relation 0 freq-table: request for target 8571 kHz (relation: 0) for cpu 0 freq-table: target is 0 (60000 kHz, 0) cpufreq-core: notification 0 of frequency transition to 60000 kHz toshiba_freq: toshiba_freq: attempting to set frequency to 60000 kHz cpufreq-core: notification 1 of frequency transition to 60000 kHz cpufreq-core: scaling loops_per_jiffy to 601851 for frequency 60000 kHz Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing some ticks... checking if CPU frequency changed. Losing too many ticks! TSC cannot be used as a timesource. Possible reasons for this are: You're running with Speedstep, You don't have DMA enabled for your hard disk (see hdparm), Incorrect TSC synchronization on an SMP system (see dmesg). Falling back to a sane timesource now. Losing some ticks... checking if CPU frequency changed. cpufreq-core: target for CPU 0: 120000 kHz, relation 1 freq-table: request for target 120000 kHz (relation: 1) for cpu 0 freq-table: target is 1 (120000 kHz, 1) cpufreq-core: notification 0 of frequency transition to 120000 kHz cpufreq-core: scaling loops_per_jiffy to 1203703 for frequency 120000 kHz toshiba_freq: toshiba_freq: attempting to set frequency to 120000 kHz toshiba_freq: toshiba_freq: SMM took 807552 cycles cpufreq-core: notification 1 of frequency transition to 120000 kHz cpufreq-core: target for CPU 0: 3428 kHz, relation 0 freq-table: request for target 3428 kHz (relation: 0) for cpu 0 freq-table: target is 0 (60000 kHz, 0) cpufreq-core: notification 0 of frequency transition to 60000 kHz [-- Attachment #4: Type: text/plain, Size: 147 bytes --] _______________________________________________ Cpufreq mailing list Cpufreq@lists.linux.org.uk http://lists.linux.org.uk/mailman/listinfo/cpufreq ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 14:13 ` Ryan Underwood @ 2006-09-22 14:39 ` Ryan Underwood 2006-09-22 15:48 ` Bruno Ducrot 2006-09-22 15:51 ` Dave Jones 0 siblings, 2 replies; 29+ messages in thread From: Ryan Underwood @ 2006-09-22 14:39 UTC (permalink / raw) To: Ryan Underwood; +Cc: Dave Jones, Ryan Underwood, Cpufreq On Fri, Sep 22, 2006 at 09:13:18AM -0500, Ryan Underwood wrote: > > I have a question, how critical is it that I have exactly the correct > CPU MHz for the scaling to work properly? Unfortunately, for the slow > speed there is no way for me to know what it actually is on a particular > system due to limitations of the firmware, so the best I could do is a > RDTSC timing to try to figure it out. I wonder if skew between the > actual CPU speed and what cpufreq thinks it is would be the source of > the problem. Hmm, this might have been the problem. On my machine, the fast and slow MHz (as measured by my TSC routine) are the same. However, the machine is noticeably slower at the 'slow' firmware setting. I thought maybe they were disabling L1 cache, but that is not the case. The CPU is a Pentium VRT 120MHZ so I'm not sure what is going on.... maybe down clocking the system bus or memory or inserting wait states somewhere. In any case, since the fast and slow MHZ are the same, cpufreq does nothing. But cpufreq should still do "something" in this case, since something else that my driver does is to disable the L2 cache when going to the slow state, which is a decent power savings even on my laptop that doesn't have an actual slow MHZ. But since the fast and slow mhz are the same, cpufreq performs no actions. -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 14:39 ` Ryan Underwood @ 2006-09-22 15:48 ` Bruno Ducrot 2006-09-22 16:01 ` Ryan Underwood 2006-09-22 15:51 ` Dave Jones 1 sibling, 1 reply; 29+ messages in thread From: Bruno Ducrot @ 2006-09-22 15:48 UTC (permalink / raw) To: nemesis; +Cc: Dave Jones, Cpufreq On Fri, Sep 22, 2006 at 09:39:54AM -0500, Ryan Underwood wrote: > > On Fri, Sep 22, 2006 at 09:13:18AM -0500, Ryan Underwood wrote: > > > > I have a question, how critical is it that I have exactly the correct > > CPU MHz for the scaling to work properly? Unfortunately, for the slow > > speed there is no way for me to know what it actually is on a particular > > system due to limitations of the firmware, so the best I could do is a > > RDTSC timing to try to figure it out. I wonder if skew between the > > actual CPU speed and what cpufreq thinks it is would be the source of > > the problem. > > Hmm, this might have been the problem. On my machine, the fast and slow > MHz (as measured by my TSC routine) are the same. However, the machine > is noticeably slower at the 'slow' firmware setting. I thought maybe > they were disabling L1 cache, but that is not the case. The CPU is a > Pentium VRT 120MHZ so I'm not sure what is going on.... maybe down > clocking the system bus or memory or inserting wait states somewhere. > > In any case, since the fast and slow MHZ are the same, cpufreq does > nothing. But cpufreq should still do "something" in this case, since > something else that my driver does is to disable the L2 cache when going > to the slow state, which is a decent power savings even on my laptop > that doesn't have an actual slow MHZ. But since the fast and slow mhz > are the same, cpufreq performs no actions. > I've seen toshiba laptop using throttling when HCI is used. If you have the datasheet of the southbridge I think we should be able to verify this hypothesis. -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 15:48 ` Bruno Ducrot @ 2006-09-22 16:01 ` Ryan Underwood 0 siblings, 0 replies; 29+ messages in thread From: Ryan Underwood @ 2006-09-22 16:01 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Dave Jones, Cpufreq, nemesis On Fri, Sep 22, 2006 at 05:48:21PM +0200, Bruno Ducrot wrote: > > I've seen toshiba laptop using throttling when HCI is used. > If you have the datasheet of the southbridge I think we should be > able to verify this hypothesis. It's a Toshiba integrated south bridge/super IO, so no luck there. I'll try to find another laptop to test it on. -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 14:39 ` Ryan Underwood 2006-09-22 15:48 ` Bruno Ducrot @ 2006-09-22 15:51 ` Dave Jones 1 sibling, 0 replies; 29+ messages in thread From: Dave Jones @ 2006-09-22 15:51 UTC (permalink / raw) To: nemesis; +Cc: Cpufreq On Fri, Sep 22, 2006 at 09:39:54AM -0500, Ryan Underwood wrote: > > On Fri, Sep 22, 2006 at 09:13:18AM -0500, Ryan Underwood wrote: > > > > I have a question, how critical is it that I have exactly the correct > > CPU MHz for the scaling to work properly? Unfortunately, for the slow > > speed there is no way for me to know what it actually is on a particular > > system due to limitations of the firmware, so the best I could do is a > > RDTSC timing to try to figure it out. I wonder if skew between the > > actual CPU speed and what cpufreq thinks it is would be the source of > > the problem. > > Hmm, this might have been the problem. On my machine, the fast and slow > MHz (as measured by my TSC routine) are the same. However, the machine > is noticeably slower at the 'slow' firmware setting. I thought maybe > they were disabling L1 cache, but that is not the case. The CPU is a > Pentium VRT 120MHZ so I'm not sure what is going on.... maybe down > clocking the system bus or memory or inserting wait states somewhere. > > In any case, since the fast and slow MHZ are the same, cpufreq does > nothing. But cpufreq should still do "something" in this case, since > something else that my driver does is to disable the L2 cache when going > to the slow state, which is a decent power savings even on my laptop > that doesn't have an actual slow MHZ. But since the fast and slow mhz > are the same, cpufreq performs no actions. *shrug*, I'm out of ideas. I looked over your code, and it seems to be correctly doing notifications when it performs a transition, which should be taking care of the timing issues for you. Puzzlings. Dave ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-21 18:48 writing a cpufreq driver Ryan Underwood 2006-09-21 19:31 ` Dave Jones @ 2006-09-22 15:39 ` Bruno Ducrot 2006-09-22 16:00 ` Ryan Underwood 1 sibling, 1 reply; 29+ messages in thread From: Bruno Ducrot @ 2006-09-22 15:39 UTC (permalink / raw) To: nemesis; +Cc: Cpufreq On Thu, Sep 21, 2006 at 01:48:33PM -0500, Ryan Underwood wrote: > > I wrote a cpufreq target driver for older Toshiba laptops. It uses SMM > to change between a "fast" and a "slow" processing speed. I have two > remaining bugs. Any comments would be appreciated. > > 1. The first time cpufreq changes speed, I get the whole "Losing some > ticks... checking if CPU frequency changed." then eventually "Losing too > many ticks!" and timer switches to PIT. This does not happen when I use > the /dev/toshiba driver to change speeds from userspace. Not sure what > is going on here... SMI handler latency is between 6 and 7 ms. > > 2. The current CPU frequency is stored in NVRAM by the SMI handler. > Unfortunately, this means if cpufreq throttles the CPU and the system is > then rebooted, the boot process is exceedingly slow. Is there some sane > way to hook into the shutdown process to restore the appropriate values, > or is this something I have to live with? That may indicate TSC frequency is constant. Try to add a .flags = CPUFREQ_CONST_LOOPS onto the driver like this: > static struct cpufreq_driver toshiba_freq_driver = { > .get = toshiba_freq_get_cpu_frequency, > .verify = toshiba_freq_verify, > .target = toshiba_freq_target, > .init = toshiba_freq_cpu_init, > .exit = toshiba_freq_cpu_exit, > .name = "toshiba_freq", > .owner = THIS_MODULE, > .attr = toshiba_freq_attr, .flags = CPUFREQ_CONST_LOOPS, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ HERE > }; > -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 15:39 ` Bruno Ducrot @ 2006-09-22 16:00 ` Ryan Underwood 2006-09-22 16:05 ` Bruno Ducrot 0 siblings, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-22 16:00 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Cpufreq, nemesis On Fri, Sep 22, 2006 at 05:39:49PM +0200, Bruno Ducrot wrote: > That may indicate TSC frequency is constant. Try to add a > .flags = CPUFREQ_CONST_LOOPS > onto the driver like this: > > > static struct cpufreq_driver toshiba_freq_driver = { > > .get = toshiba_freq_get_cpu_frequency, > > .verify = toshiba_freq_verify, > > .target = toshiba_freq_target, > > .init = toshiba_freq_cpu_init, > > .exit = toshiba_freq_cpu_exit, > > .name = "toshiba_freq", > > .owner = THIS_MODULE, > > .attr = toshiba_freq_attr, > .flags = CPUFREQ_CONST_LOOPS, > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > HERE > > }; That worked. Looks like the CPU MHZ isn't changing really (on this machine at least). -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 16:00 ` Ryan Underwood @ 2006-09-22 16:05 ` Bruno Ducrot 2006-09-22 16:11 ` Ryan Underwood 0 siblings, 1 reply; 29+ messages in thread From: Bruno Ducrot @ 2006-09-22 16:05 UTC (permalink / raw) To: Ryan Underwood; +Cc: Cpufreq On Fri, Sep 22, 2006 at 11:00:25AM -0500, Ryan Underwood wrote: > > On Fri, Sep 22, 2006 at 05:39:49PM +0200, Bruno Ducrot wrote: > > That may indicate TSC frequency is constant. Try to add a > > .flags = CPUFREQ_CONST_LOOPS > > onto the driver like this: > > > > > static struct cpufreq_driver toshiba_freq_driver = { > > > .get = toshiba_freq_get_cpu_frequency, > > > .verify = toshiba_freq_verify, > > > .target = toshiba_freq_target, > > > .init = toshiba_freq_cpu_init, > > > .exit = toshiba_freq_cpu_exit, > > > .name = "toshiba_freq", > > > .owner = THIS_MODULE, > > > .attr = toshiba_freq_attr, > > .flags = CPUFREQ_CONST_LOOPS, > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > HERE > > > }; > > That worked. Looks like the CPU MHZ isn't changing really (on this > machine at least). > I'm now sure the southbridge is throttling the processor... -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 16:05 ` Bruno Ducrot @ 2006-09-22 16:11 ` Ryan Underwood 2006-09-23 15:07 ` Bruno Ducrot 0 siblings, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-22 16:11 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Cpufreq, Ryan Underwood On Fri, Sep 22, 2006 at 06:05:14PM +0200, Bruno Ducrot wrote: > > I'm now sure the southbridge is throttling the processor... How would it usually do this, by repeated #SMI? -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-22 16:11 ` Ryan Underwood @ 2006-09-23 15:07 ` Bruno Ducrot 2006-09-23 15:21 ` Ryan Underwood 0 siblings, 1 reply; 29+ messages in thread From: Bruno Ducrot @ 2006-09-23 15:07 UTC (permalink / raw) To: Ryan Underwood; +Cc: Cpufreq On Fri, Sep 22, 2006 at 11:11:49AM -0500, Ryan Underwood wrote: > > On Fri, Sep 22, 2006 at 06:05:14PM +0200, Bruno Ducrot wrote: > > > > I'm now sure the southbridge is throttling the processor... > > How would it usually do this, by repeated #SMI? By repeated STPCLK# I guess. IIRC i486 (and newer intel processors) had that pin. -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-23 15:07 ` Bruno Ducrot @ 2006-09-23 15:21 ` Ryan Underwood 2006-09-23 15:44 ` Bruno Ducrot 0 siblings, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-23 15:21 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Cpufreq, Ryan Underwood On Sat, Sep 23, 2006 at 05:07:52PM +0200, Bruno Ducrot wrote: > On Fri, Sep 22, 2006 at 11:11:49AM -0500, Ryan Underwood wrote: > > > > On Fri, Sep 22, 2006 at 06:05:14PM +0200, Bruno Ducrot wrote: > > > > > > I'm now sure the southbridge is throttling the processor... > > > > How would it usually do this, by repeated #SMI? > > By repeated STPCLK# I guess. IIRC i486 (and newer intel processors) had > that pin. But if it were using STPCLK, TSC would be slowed too, right? TSC just counts the clock cycles of CPU. I was thinking the method was to enter SMM and run HLT instructions or similar. That way power is saved but TSC is preserved. Unfortunately, that makes the power saving mode on this particular machine useless, since Linux already runs HLT during idle. -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-23 15:21 ` Ryan Underwood @ 2006-09-23 15:44 ` Bruno Ducrot 2006-09-23 16:03 ` Ryan Underwood 0 siblings, 1 reply; 29+ messages in thread From: Bruno Ducrot @ 2006-09-23 15:44 UTC (permalink / raw) To: Ryan Underwood; +Cc: Cpufreq On Sat, Sep 23, 2006 at 10:21:44AM -0500, Ryan Underwood wrote: > > On Sat, Sep 23, 2006 at 05:07:52PM +0200, Bruno Ducrot wrote: > > On Fri, Sep 22, 2006 at 11:11:49AM -0500, Ryan Underwood wrote: > > > > > > On Fri, Sep 22, 2006 at 06:05:14PM +0200, Bruno Ducrot wrote: > > > > > > > > I'm now sure the southbridge is throttling the processor... > > > > > > How would it usually do this, by repeated #SMI? > > > > By repeated STPCLK# I guess. IIRC i486 (and newer intel processors) had > > that pin. > > But if it were using STPCLK, TSC would be slowed too, right? TSC just > counts the clock cycles of CPU. I was thinking the method was to enter > SMM and run HLT instructions or similar. That way power is saved but > TSC is preserved. Unfortunately, that makes the power saving mode on > this particular machine useless, since Linux already runs HLT during > idle. You are right. Maybe Toshiba implemented that: http://www.freepatentsonline.com/7082542.html Cheers, -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-23 15:44 ` Bruno Ducrot @ 2006-09-23 16:03 ` Ryan Underwood 2006-09-23 16:13 ` Bruno Ducrot 0 siblings, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-23 16:03 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Cpufreq, Ryan Underwood On Sat, Sep 23, 2006 at 05:44:42PM +0200, Bruno Ducrot wrote: > > > > But if it were using STPCLK, TSC would be slowed too, right? TSC just > > counts the clock cycles of CPU. I was thinking the method was to enter > > SMM and run HLT instructions or similar. That way power is saved but > > TSC is preserved. Unfortunately, that makes the power saving mode on > > this particular machine useless, since Linux already runs HLT during > > idle. > > You are right. Maybe Toshiba implemented that: > > http://www.freepatentsonline.com/7082542.html Very good catch! -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-23 16:03 ` Ryan Underwood @ 2006-09-23 16:13 ` Bruno Ducrot 2006-09-25 15:39 ` Ryan Underwood 2006-09-25 16:44 ` Ryan Underwood 0 siblings, 2 replies; 29+ messages in thread From: Bruno Ducrot @ 2006-09-23 16:13 UTC (permalink / raw) To: Ryan Underwood; +Cc: Cpufreq On Sat, Sep 23, 2006 at 11:03:36AM -0500, Ryan Underwood wrote: > > On Sat, Sep 23, 2006 at 05:44:42PM +0200, Bruno Ducrot wrote: > > > > > > But if it were using STPCLK, TSC would be slowed too, right? TSC just > > > counts the clock cycles of CPU. I was thinking the method was to enter > > > SMM and run HLT instructions or similar. That way power is saved but > > > TSC is preserved. Unfortunately, that makes the power saving mode on > > > this particular machine useless, since Linux already runs HLT during > > > idle. > > > > You are right. Maybe Toshiba implemented that: > > > > http://www.freepatentsonline.com/7082542.html > > Very good catch! > Of course, I never wrote toshiba can invalidate this patent by earlyer works... After all we are only speculating. -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-23 16:13 ` Bruno Ducrot @ 2006-09-25 15:39 ` Ryan Underwood 2006-10-02 2:19 ` Dominik Brodowski 2006-09-25 16:44 ` Ryan Underwood 1 sibling, 1 reply; 29+ messages in thread From: Ryan Underwood @ 2006-09-25 15:39 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Cpufreq, Ryan Underwood On Sat, Sep 23, 2006 at 06:13:11PM +0200, Bruno Ducrot wrote: > On Sat, Sep 23, 2006 at 11:03:36AM -0500, Ryan Underwood wrote: > > > > On Sat, Sep 23, 2006 at 05:44:42PM +0200, Bruno Ducrot wrote: > > > > > > > > But if it were using STPCLK, TSC would be slowed too, right? TSC just > > > > counts the clock cycles of CPU. I was thinking the method was to enter > > > > SMM and run HLT instructions or similar. That way power is saved but > > > > TSC is preserved. Unfortunately, that makes the power saving mode on > > > > this particular machine useless, since Linux already runs HLT during > > > > idle. > > > > > > You are right. Maybe Toshiba implemented that: > > > > > > http://www.freepatentsonline.com/7082542.html > > > > Very good catch! > > > > Of course, I never wrote toshiba can invalidate this patent by earlyer > works... After all we are only speculating. So I did some more poking around.. this is from the system maintenance manual: System Controller Gate Array This gate array has the following functions: CPU interface/control Level-2 cache memory control DRAM control PCI master/slave interface Write buffer (CPU-DRAM, CPU-PCI, PCI-DRAM) Prefetch buffer (PCI-PCI, PCI-DRAM) Two DMACs: 82C37 equivalent Two PICs: 82C59 equivalent One PIT: 82C54 equivalent Serial interrupt function Power management control Suspend/resume control CPU stop clock function <----- Interesting that if it were SMI throttling, they would refer to it as "stop clock". I wonder if anyone can tell us whether STPCLK stops TSC or not. -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-25 15:39 ` Ryan Underwood @ 2006-10-02 2:19 ` Dominik Brodowski 0 siblings, 0 replies; 29+ messages in thread From: Dominik Brodowski @ 2006-10-02 2:19 UTC (permalink / raw) To: Ryan Underwood; +Cc: Cpufreq, Bruno Ducrot On Mon, Sep 25, 2006 at 10:39:14AM -0500, Ryan Underwood wrote: > Interesting that if it were SMI throttling, they would refer to it as > "stop clock". I wonder if anyone can tell us whether STPCLK stops TSC > or not. As far as I know, the TSC is usually stopped when triggering STPCLK on an "older" CPU. Does the battery run-time increase when you use your driver? Then it's doing _something_ , even if we do not know what it does exactly :) Dominik ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver 2006-09-23 16:13 ` Bruno Ducrot 2006-09-25 15:39 ` Ryan Underwood @ 2006-09-25 16:44 ` Ryan Underwood 1 sibling, 0 replies; 29+ messages in thread From: Ryan Underwood @ 2006-09-25 16:44 UTC (permalink / raw) To: Bruno Ducrot; +Cc: Cpufreq, Ryan Underwood On Sat, Sep 23, 2006 at 06:13:11PM +0200, Bruno Ducrot wrote: > On Sat, Sep 23, 2006 at 11:03:36AM -0500, Ryan Underwood wrote: > > > > On Sat, Sep 23, 2006 at 05:44:42PM +0200, Bruno Ducrot wrote: > > > > > > > > But if it were using STPCLK, TSC would be slowed too, right? TSC just > > > > counts the clock cycles of CPU. I was thinking the method was to enter > > > > SMM and run HLT instructions or similar. That way power is saved but > > > > TSC is preserved. Unfortunately, that makes the power saving mode on > > > > this particular machine useless, since Linux already runs HLT during > > > > idle. Hmm: 24319201.pdf Intel P3 system programmers guide, page 425. "The counter is incremented on every processor clock cycle, even when the processor is halted by the HLT instruction or the external STPCLK# pin" So maybe it is using STPCLK after all. Certainly seems like counter intuitive behavior though. -- Ryan Underwood, <nemesis@icequake.net> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: writing a cpufreq driver
@ 2006-09-22 16:31 Erik Slagter
2006-09-23 15:31 ` Bruno Ducrot
0 siblings, 1 reply; 29+ messages in thread
From: Erik Slagter @ 2006-09-22 16:31 UTC (permalink / raw)
To: Cpufreq
> I'm now sure the southbridge is throttling the processor...
I was always told that throttling the processor doesn't yield any
powersaving? And that is exactly what my last two motherboards show.
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: writing a cpufreq driver 2006-09-22 16:31 Erik Slagter @ 2006-09-23 15:31 ` Bruno Ducrot 0 siblings, 0 replies; 29+ messages in thread From: Bruno Ducrot @ 2006-09-23 15:31 UTC (permalink / raw) To: Erik Slagter; +Cc: Cpufreq On Fri, Sep 22, 2006 at 06:31:56PM +0200, Erik Slagter wrote: > > I'm now sure the southbridge is throttling the processor... > > I was always told that throttling the processor doesn't yield any > powersaving? And that is exactly what my last two motherboards show. In fact this depend if frequency and 'performance for a given task' is linear or not. On older systems (as the one from the OP) there is an huge performance penalty (external L2 cache if even there is one) when running at full. Throttling the processor can then achieve power saving. -- Bruno Ducrot -- Which is worse: ignorance or apathy? -- Don't know. Don't care. ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2006-10-02 2:19 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-09-21 18:48 writing a cpufreq driver Ryan Underwood 2006-09-21 19:31 ` Dave Jones 2006-09-21 19:38 ` Langsdorf, Mark 2006-09-21 19:47 ` Dave Jones 2006-09-22 15:44 ` Bruno Ducrot 2006-09-22 15:49 ` Dave Jones 2006-09-21 20:08 ` Ryan Underwood 2006-09-21 20:44 ` Dave Jones 2006-09-21 21:03 ` Ryan Underwood 2006-09-21 21:13 ` Dave Jones 2006-09-22 14:13 ` Ryan Underwood 2006-09-22 14:39 ` Ryan Underwood 2006-09-22 15:48 ` Bruno Ducrot 2006-09-22 16:01 ` Ryan Underwood 2006-09-22 15:51 ` Dave Jones 2006-09-22 15:39 ` Bruno Ducrot 2006-09-22 16:00 ` Ryan Underwood 2006-09-22 16:05 ` Bruno Ducrot 2006-09-22 16:11 ` Ryan Underwood 2006-09-23 15:07 ` Bruno Ducrot 2006-09-23 15:21 ` Ryan Underwood 2006-09-23 15:44 ` Bruno Ducrot 2006-09-23 16:03 ` Ryan Underwood 2006-09-23 16:13 ` Bruno Ducrot 2006-09-25 15:39 ` Ryan Underwood 2006-10-02 2:19 ` Dominik Brodowski 2006-09-25 16:44 ` Ryan Underwood -- strict thread matches above, loose matches on Subject: below -- 2006-09-22 16:31 Erik Slagter 2006-09-23 15:31 ` Bruno Ducrot
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.