* 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 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: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-21 18:48 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-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 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: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-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-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 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 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: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: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-22 16:31 writing a cpufreq driver 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
* 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-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-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
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-22 16:31 writing a cpufreq driver Erik Slagter
2006-09-23 15:31 ` Bruno Ducrot
-- strict thread matches above, loose matches on Subject: below --
2006-09-21 18:48 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
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.