2005-02-08 17:43:35 +00:00
|
|
|
.\" Copyright (c) 2005 Nate Lawson
|
|
|
|
.\" All rights reserved.
|
|
|
|
.\"
|
|
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
|
|
.\" modification, are permitted provided that the following conditions
|
|
|
|
.\" are met:
|
|
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
|
|
.\"
|
|
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
.\" SUCH DAMAGE.
|
|
|
|
.\"
|
|
|
|
.\" $FreeBSD$
|
|
|
|
.\"
|
2005-02-14 18:17:47 +00:00
|
|
|
.Dd February 14, 2005
|
2005-02-08 17:43:35 +00:00
|
|
|
.Dt CPUFREQ 4
|
|
|
|
.Os
|
|
|
|
.Sh NAME
|
|
|
|
.Nm cpufreq
|
|
|
|
.Nd CPU frequency control framework
|
|
|
|
.Sh SYNOPSIS
|
|
|
|
.Cd "device cpufreq"
|
|
|
|
.Pp
|
|
|
|
.In sys/cpu.h
|
|
|
|
.Ft int
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_levels "device_t dev" "struct cf_level *levels" "int *count"
|
2005-02-08 17:43:35 +00:00
|
|
|
.Ft int
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_set "device_t dev" "const struct cf_level *level" "int priority"
|
2005-02-08 17:43:35 +00:00
|
|
|
.Ft int
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_get "device_t dev" "struct cf_level *level"
|
2005-02-08 17:43:35 +00:00
|
|
|
.Ft int
|
|
|
|
.Fo cpufreq_drv_settings
|
|
|
|
.Fa "device_t dev"
|
|
|
|
.Fa "struct cf_setting *sets"
|
|
|
|
.Fa "int *count"
|
|
|
|
.Fa "int *type"
|
|
|
|
.Fc
|
|
|
|
.Ft int
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_drv_set "device_t dev" "const struct cf_setting *set"
|
2005-02-08 17:43:35 +00:00
|
|
|
.Ft int
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_drv_get "device_t dev" "struct cf_setting *set"
|
2005-02-08 17:43:35 +00:00
|
|
|
.Sh DESCRIPTION
|
|
|
|
The
|
|
|
|
.Nm
|
|
|
|
driver provides a unified kernel and user interface to CPU frequency
|
|
|
|
control drivers.
|
|
|
|
It combines multiple drivers offering different settings into a single
|
|
|
|
interface of all possible levels.
|
|
|
|
Users can access this interface directly via
|
|
|
|
.Xr sysctl 8
|
|
|
|
or by indicating to
|
|
|
|
.Xr power_profile 8
|
|
|
|
that it should switch settings when the AC line state changes via
|
|
|
|
.Xr rc.conf 5 .
|
|
|
|
.Sh SYSCTLS
|
|
|
|
These settings may be overridden by kernel drivers requesting alternate
|
|
|
|
settings.
|
|
|
|
If this occurs, the original values will be restored once the condition
|
2005-02-13 21:29:28 +00:00
|
|
|
has passed (e.g., the system has cooled sufficiently).
|
|
|
|
If a sysctl cannot be set due to an override condition, it will return
|
|
|
|
.Er EPERM .
|
2005-02-08 17:43:35 +00:00
|
|
|
.Bl -tag -width indent
|
|
|
|
.It Va dev.cpu.%d.freq
|
|
|
|
Current active CPU frequency in MHz.
|
|
|
|
.It Va dev.cpu.%d.freq_levels
|
|
|
|
Currently available levels for the CPU frequency and power usage for each.
|
|
|
|
Values are in units of MHz and milliwatts.
|
|
|
|
.El
|
|
|
|
.Sh SUPPORTED DRIVERS
|
|
|
|
The following device drivers offer absolute frequency control via the
|
|
|
|
.Nm
|
|
|
|
interface.
|
|
|
|
Usually, only one of these can be active at a time.
|
|
|
|
.Pp
|
|
|
|
.Bl -tag -compact -width ".Xr acpi_perf 4"
|
|
|
|
.It Xr acpi_perf 4
|
|
|
|
ACPI CPU performance states
|
|
|
|
.It Xr ichss 4
|
|
|
|
Intel SpeedStep for ICH
|
|
|
|
.El
|
|
|
|
.Pp
|
|
|
|
The following device drivers offer relative frequency control and
|
|
|
|
have an additive effect:
|
|
|
|
.Pp
|
2005-02-13 21:29:28 +00:00
|
|
|
.Bl -tag -compact -width ".Xr acpi_throttle 4"
|
2005-02-08 17:43:35 +00:00
|
|
|
.It Xr acpi_throttle 4
|
|
|
|
ACPI CPU throttling
|
|
|
|
.El
|
|
|
|
.Sh KERNEL INTERFACE
|
|
|
|
Kernel components can query and set CPU frequencies through the
|
|
|
|
.Nm
|
|
|
|
kernel interface.
|
|
|
|
This involves obtaining a
|
|
|
|
.Nm
|
|
|
|
device, calling
|
|
|
|
.Fn cpufreq_levels
|
|
|
|
to get the currently available frequency levels,
|
|
|
|
checking the current level with
|
|
|
|
.Fn cpufreq_get ,
|
|
|
|
and setting a new one from the list with
|
|
|
|
.Fn cpufreq_set .
|
|
|
|
Each level may actually reference more than one
|
|
|
|
.Nm
|
|
|
|
driver but kernel components do not need to be aware of this.
|
|
|
|
The
|
2005-02-13 21:29:28 +00:00
|
|
|
.Va total_set
|
2005-02-08 17:43:35 +00:00
|
|
|
element of
|
2005-02-13 21:29:28 +00:00
|
|
|
.Vt "struct cf_level"
|
2005-02-08 17:43:35 +00:00
|
|
|
provides a summary of the frequency and power for this level.
|
|
|
|
Unknown or irrelevant values are set to
|
2005-02-13 21:29:28 +00:00
|
|
|
.Dv CPUFREQ_VAL_UNKNOWN .
|
2005-02-08 17:43:35 +00:00
|
|
|
.Pp
|
|
|
|
The
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_levels
|
2005-02-08 17:43:35 +00:00
|
|
|
method takes a
|
|
|
|
.Nm
|
|
|
|
device and an empty array of
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa levels .
|
2005-02-08 17:43:35 +00:00
|
|
|
The
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa count
|
2005-02-08 17:43:35 +00:00
|
|
|
value should be set to the number of levels available and after the
|
|
|
|
function completes, will be set to the actual number of levels returned.
|
|
|
|
If there are more levels than
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa count
|
|
|
|
will allow, it should return
|
|
|
|
.Er E2BIG .
|
2005-02-08 17:43:35 +00:00
|
|
|
.Pp
|
|
|
|
The
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_get
|
2005-02-08 17:43:35 +00:00
|
|
|
method takes a pointer to space to store a
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa level .
|
2005-02-08 17:43:35 +00:00
|
|
|
After successful completion, the output will be the current active level
|
|
|
|
and is equal to one of the levels returned by
|
|
|
|
.Fn cpufreq_levels .
|
|
|
|
.Pp
|
|
|
|
The
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fn cpufreq_set
|
2005-02-08 17:43:35 +00:00
|
|
|
method takes a pointer a
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa level
|
2005-02-08 17:43:35 +00:00
|
|
|
and attempts to activate it.
|
|
|
|
The
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa priority
|
|
|
|
(i.e.,
|
|
|
|
.Dv CPUFREQ_PRIO_KERN )
|
2005-02-08 17:43:35 +00:00
|
|
|
tells
|
|
|
|
.Nm
|
|
|
|
whether to override previous settings while activating this level.
|
|
|
|
If
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa priority
|
2005-02-08 17:43:35 +00:00
|
|
|
is higher than the current active level, that level will be saved and
|
|
|
|
overridden with the new level.
|
2005-02-14 18:17:47 +00:00
|
|
|
If a level is already saved, the new level is set without overwriting
|
|
|
|
the older saved level.
|
2005-02-08 17:43:35 +00:00
|
|
|
If
|
|
|
|
.Fn cpufreq_set
|
2005-02-13 21:29:28 +00:00
|
|
|
is called with a
|
|
|
|
.Dv NULL
|
|
|
|
.Fa level ,
|
2005-02-14 18:17:47 +00:00
|
|
|
the saved level will be restored.
|
|
|
|
If there is no saved level,
|
|
|
|
.Fn cpufreq_set
|
|
|
|
will return
|
|
|
|
.Er ENXIO .
|
2005-02-08 17:43:35 +00:00
|
|
|
If
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa priority
|
2005-02-08 17:43:35 +00:00
|
|
|
is lower than the current active level's priority, this method returns
|
2005-02-13 21:29:28 +00:00
|
|
|
.Er EPERM .
|
2005-02-08 17:43:35 +00:00
|
|
|
.Sh DRIVER INTERFACE
|
|
|
|
Kernel drivers offering hardware-specific CPU frequency control export
|
|
|
|
their individual settings through the
|
|
|
|
.Nm
|
|
|
|
driver interface.
|
|
|
|
This involves implementing three methods:
|
|
|
|
.Fn cpufreq_drv_settings ,
|
|
|
|
.Fn cpufreq_drv_set ,
|
|
|
|
and
|
|
|
|
.Fn cpufreq_drv_get .
|
|
|
|
Additionally, the driver must attach a device as a child of a CPU
|
|
|
|
device so that these methods can be called by the
|
|
|
|
.Nm
|
|
|
|
framework.
|
|
|
|
.Pp
|
|
|
|
The
|
|
|
|
.Fn cpufreq_drv_settings
|
|
|
|
method returns an array of currently available settings, each of type
|
2005-02-13 21:29:28 +00:00
|
|
|
.Vt "struct cf_setting" .
|
2005-02-08 17:43:35 +00:00
|
|
|
The driver should set unknown or irrelevant values to
|
2005-02-13 21:29:28 +00:00
|
|
|
.Dv CPUFREQ_VAL_UNKNOWN .
|
2005-02-08 17:43:35 +00:00
|
|
|
All the following elements for each setting should be returned:
|
|
|
|
.Bd -literal
|
|
|
|
struct cf_setting {
|
|
|
|
int freq; /* CPU clock in Mhz or 100ths of a percent. */
|
|
|
|
int volts; /* Voltage in mV. */
|
|
|
|
int power; /* Power consumed in mW. */
|
|
|
|
int lat; /* Transition latency in us. */
|
|
|
|
device_t dev; /* Driver providing this setting. */
|
|
|
|
};
|
|
|
|
.Ed
|
|
|
|
.Pp
|
|
|
|
On entry to this method,
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa count
|
2005-02-08 17:43:35 +00:00
|
|
|
contains the number of settings that can be returned.
|
|
|
|
On successful completion, the driver sets it to the actual number of
|
|
|
|
settings returned.
|
|
|
|
If the driver offers more settings than
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa count
|
|
|
|
will allow, it should return
|
|
|
|
.Er E2BIG .
|
2005-02-08 17:43:35 +00:00
|
|
|
The driver sets
|
2005-02-13 21:29:28 +00:00
|
|
|
.Fa type
|
2005-02-08 17:43:35 +00:00
|
|
|
to the type of settings it offers, either
|
2005-02-13 21:29:28 +00:00
|
|
|
.Dv CPUFREQ_TYPE_ABSOLUTE
|
2005-02-08 17:43:35 +00:00
|
|
|
or
|
2005-02-13 21:29:28 +00:00
|
|
|
.Dv CPUFREQ_TYPE_RELATIVE .
|
2005-02-08 17:43:35 +00:00
|
|
|
.Pp
|
|
|
|
The
|
|
|
|
.Fn cpufreq_drv_set
|
|
|
|
method takes a driver setting and makes it active.
|
|
|
|
If the setting is invalid or not currently available, it should return
|
2005-02-13 21:29:28 +00:00
|
|
|
.Er EINVAL .
|
2005-02-08 17:43:35 +00:00
|
|
|
.Pp
|
|
|
|
The
|
|
|
|
.Fn cpufreq_drv_get
|
|
|
|
method returns the currently-active driver setting.
|
|
|
|
The
|
2005-02-13 21:29:28 +00:00
|
|
|
.Vt "struct cf_setting"
|
2005-02-08 17:43:35 +00:00
|
|
|
returned must be valid for passing to
|
|
|
|
.Fn cpufreq_drv_set ,
|
|
|
|
including all elements being filled out correctly.
|
|
|
|
If the driver cannot infer the current setting
|
|
|
|
(even by estimating it with
|
|
|
|
.Fn cpu_est_clockrate )
|
|
|
|
then it should set all elements to
|
2005-02-13 21:29:28 +00:00
|
|
|
.Dv CPUFREQ_VAL_UNKNOWN .
|
|
|
|
.Sh SEE ALSO
|
|
|
|
.Xr acpi 4 ,
|
|
|
|
.Xr sysctl 8
|
|
|
|
.Sh AUTHORS
|
|
|
|
.An Nate Lawson
|
2005-02-08 17:43:35 +00:00
|
|
|
.Sh BUGS
|
|
|
|
The following drivers have not yet been converted to the
|
|
|
|
.Nm
|
|
|
|
interface:
|
|
|
|
.Xr longrun 4 ,
|
|
|
|
.Xr p4tcc 4 .
|
|
|
|
.Pp
|
2005-02-14 18:17:47 +00:00
|
|
|
Notification of CPU and bus frequency changes is not implemented yet.
|
2005-02-08 17:43:35 +00:00
|
|
|
.Pp
|
|
|
|
When multiple CPUs offer frequency control, they cannot be set to different
|
|
|
|
levels and must all offer the same frequency settings.
|