67fcddd627
not be used before interrupts have been enabled. Suggested by macallan@.
315 lines
8.4 KiB
Groff
315 lines
8.4 KiB
Groff
.\" $NetBSD: cpufreq.9,v 1.6 2011/10/27 05:25:08 jruoho Exp $ */
|
|
.\"
|
|
.\" Copyright (c) 2011 Jukka Ruohonen <jruohonen.iki.fi>
|
|
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
|
.\"
|
|
.Dd October 27, 2011
|
|
.Dt CPUFREQ 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm cpufreq ,
|
|
.Nm cpufreq_register ,
|
|
.Nm cpufreq_deregister ,
|
|
.Nm cpufreq_suspend ,
|
|
.Nm cpufreq_resume ,
|
|
.Nm cpufreq_get ,
|
|
.Nm cpufreq_get_backend ,
|
|
.Nm cpufreq_get_state ,
|
|
.Nm cpufreq_get_state_index ,
|
|
.Nm cpufreq_set ,
|
|
.Nm cpufreq_set_all
|
|
.Nd interface for CPU frequency scaling
|
|
.Sh SYNOPSIS
|
|
.In sys/cpufreq.h
|
|
.Ft int
|
|
.Fn cpufreq_register "struct cpufreq *cf"
|
|
.Ft void
|
|
.Fn cpufreq_deregister "void"
|
|
.Ft void
|
|
.Fn cpufreq_suspend "struct cpu_info *ci"
|
|
.Ft void
|
|
.Fn cpufreq_resume "struct cpu_info *ci"
|
|
.Ft uint32_t
|
|
.Fn cpufreq_get "struct cpu_info *ci"
|
|
.Ft int
|
|
.Fn cpufreq_get_backend "struct cpufreq *cf"
|
|
.Ft int
|
|
.Fn cpufreq_get_state "uint32_t freq" "struct cpufreq_state *cfs"
|
|
.Ft int
|
|
.Fn cpufreq_get_state_index "uint32_t index" "struct cpufreq_state *cfs"
|
|
.Ft void
|
|
.Fn cpufreq_set "struct cpu_info *ci" "uint32_t freq"
|
|
.Ft void
|
|
.Fn cpufreq_set_all "uint32_t freq"
|
|
.\" .Ft void
|
|
.\" .Fn cpufreq_set_higher "struct cpu_info *ci"
|
|
.\" .Ft void
|
|
.\" .Fn cpufreq_set_lower "struct cpu_info *ci"
|
|
.Sh DESCRIPTION
|
|
The machine-independent
|
|
.Nm
|
|
interface provides a framework for
|
|
.Tn CPU
|
|
frequency scaling done by a machine-dependent backend implementation.
|
|
User space control is available via
|
|
.Xr cpuctl 8 .
|
|
.Pp
|
|
The
|
|
.Nm
|
|
interface is a per-CPU framework.
|
|
It is implicitly assumed that the frequency can be set
|
|
independently for all processors in the system.
|
|
However,
|
|
.Nm
|
|
does not imply any restrictions upon whether this information
|
|
is utilized by the actual machine-dependent implementation.
|
|
It is possible to use
|
|
.Nm
|
|
with frequency scaling implemented via
|
|
.Xr pci 4 .
|
|
In addition, it assumed that the available frequency levels are
|
|
shared uniformly by all processors in the system,
|
|
even when it is possible to control the frequency of individual processors.
|
|
.Pp
|
|
It should be noted that the
|
|
.Nm
|
|
interface is generally stateless.
|
|
This implies for instance that possible caching should
|
|
be done in the machine-dependent backend.
|
|
The
|
|
.Fn cpufreq_suspend
|
|
and
|
|
.Fn cpufreq_resume
|
|
functions are exceptions.
|
|
These can be integrated with
|
|
.Xr pmf 9 .
|
|
.Sh FUNCTIONS
|
|
.Bl -tag -width compact
|
|
.It Fn cpufreq_register "cf"
|
|
The
|
|
.Fn cpufreq_register
|
|
function initializes the interface by associating
|
|
a machine-dependent backend with the framework.
|
|
Only one backend can be registered.
|
|
Upon successful completion,
|
|
.Fn cpufreq_register
|
|
returns 0 and sets the frequency of all processors
|
|
to the maximum available level.
|
|
Note that the registration can be done
|
|
only after interrupts have been enabled; cf.
|
|
.Xr config_interrupts 9 .
|
|
.Pp
|
|
The following elements in
|
|
.Vt struct cpufreq
|
|
should be filled prior to the call:
|
|
.Bd -literal -offset indent
|
|
char cf_name[CPUFREQ_NAME_MAX];
|
|
struct cpufreq_state cf_state[CPUFREQ_STATE_MAX];
|
|
uint32_t cf_state_count;
|
|
bool cf_mp;
|
|
void *cf_cookie;
|
|
xcfunc_t cf_get_freq;
|
|
xcfunc_t cf_set_freq;
|
|
.Ed
|
|
.Pp
|
|
.Bl -bullet
|
|
.It
|
|
The name of the backend should be given in
|
|
.Vt cf_name .
|
|
.It
|
|
The
|
|
.Vt cpufreq_state
|
|
structure conveys descriptive information about the frequency states.
|
|
The following fields can be used for the registration:
|
|
.Bd -literal -offset 2n
|
|
uint32_t cfs_freq;
|
|
uint32_t cfs_power;
|
|
.Ed
|
|
.Pp
|
|
From these
|
|
.Vt cfs_freq
|
|
(the clock frequency in MHz) is mandatory, whereas the optional
|
|
.Vt cfs_power
|
|
can be filled to describe the power consumption (in mW) of each state.
|
|
The
|
|
.Fa cf_state
|
|
array must be filled in descending order, that is, the highest
|
|
frequency should be at the zero index.
|
|
.Pp
|
|
If the backend operates with a simple boolean switch
|
|
without knowing the clock frequencies, the
|
|
.Fa cfs_freq
|
|
field should be set to
|
|
.Dv CPUFREQ_STATE_ENABLED
|
|
or
|
|
.Dv CPUFREQ_STATE_DISABLED .
|
|
The first constant should precede the latter one in
|
|
.Vt cf_state .
|
|
.It
|
|
The
|
|
.Vt cf_state_count
|
|
field defines the number of states that the backend has filled in the
|
|
.Vt cf_state
|
|
array.
|
|
.It
|
|
The
|
|
.Vt cf_mp
|
|
boolean should be set to false if it is known that the backend
|
|
can not handle per-CPU frequency states;
|
|
changes should always be propagated
|
|
to all processors in the system.
|
|
.It
|
|
The
|
|
.Vt cf_cookie
|
|
field is an opaque pointer passed to the backend when
|
|
.Fn cpufreq_get ,
|
|
.Fn cpufreq_set ,
|
|
or
|
|
.Fn cpufreq_set_all
|
|
is called.
|
|
.It
|
|
The
|
|
.Vt cf_get_freq
|
|
and
|
|
.Vt cf_set_freq
|
|
are function pointers that should be associated with the
|
|
machine-dependent functions to get and set a frequency, respectively.
|
|
The
|
|
.Vt xcfunc_t
|
|
type is part of
|
|
.Xr xcall 9 .
|
|
When the function pointers are invoked by
|
|
.Nm ,
|
|
the first parameter is always the
|
|
.Vt cf_cookie
|
|
and the second parameter is the frequency, defined as
|
|
.Vt uint32_t * .
|
|
.El
|
|
.It Fn cpufreq_deregister
|
|
Deregisters any possible backend in use.
|
|
.It Fn cpufreq_suspend "ci"
|
|
The
|
|
.Fn cpufreq_suspend
|
|
can be called when the processor suspends.
|
|
The function saves the current frequency of
|
|
.Fa ci
|
|
and sets the minimum available frequency.
|
|
.It Fn cpufreq_resume "ci"
|
|
Resumes the frequency of
|
|
.Fa ci
|
|
that was used before suspend.
|
|
.It Fn cpufreq_get "ci"
|
|
Returns the current frequency of the processor
|
|
.Fa ci .
|
|
A value zero is returned upon failure.
|
|
.It Fn cpufreq_get_backend "cf"
|
|
Upon successful completion,
|
|
.Fn cpufreq_get_backend
|
|
returns 0 and fills
|
|
.Fa cf
|
|
with the data related to the currently used backend.
|
|
.It Fn cpufreq_get_state "freq" "cfs"
|
|
The
|
|
.Fn cpufreq_get_state
|
|
function looks for the given frequency
|
|
from the array of known frequency states.
|
|
If
|
|
.Fa freq
|
|
is not found, the closest match is returned.
|
|
Upon successful completion,
|
|
the function returns zero and stores the state information to
|
|
.Fa cfs .
|
|
.It Fn cpufreq_get_state_index "index" "cfs"
|
|
Stores the frequency state with the given
|
|
.Fa index
|
|
to
|
|
.Fa cfs ,
|
|
returning zero upon successful completion.
|
|
.It Fn cpufreq_set "ci" "freq"
|
|
The
|
|
.Fn cpufreq_set
|
|
function sets the frequency of
|
|
.Fa ci
|
|
to
|
|
.Fa freq .
|
|
.It Fn cpufreq_set_all "freq"
|
|
Sets
|
|
.Fa freq
|
|
for all processors in the system.
|
|
.\" .It Fn cpufreq_set_higher "ci"
|
|
.\" Decrements the current frequency level of
|
|
.\" .Fa ci
|
|
.\" by one state.
|
|
.\" .It Fn cpufreq_set_lower "ci"
|
|
.\" Increases the current frequency state of
|
|
.\" .Fa ci
|
|
.\" by one state.
|
|
.El
|
|
.Pp
|
|
The three functions
|
|
.Fn cpufreq_get ,
|
|
.Fn cpufreq_set ,
|
|
and
|
|
.Fn cpufreq_set_all
|
|
guarantee that the call will be made in
|
|
.Xr curcpu 9 .
|
|
The interface holds a
|
|
.Xr mutex 9
|
|
while calling the functions.
|
|
This, and the use of
|
|
.Xr xcall 9 ,
|
|
implies that no memory can be allocated in the backend during the calls.
|
|
Nor should the functions be called from interrupt context.
|
|
.Sh CODE REFERENCES
|
|
The
|
|
.Nm
|
|
interface is implemented within
|
|
.Pa sys/kern/subr_cpufreq.c .
|
|
.Sh SEE ALSO
|
|
.Xr cpuctl 8 ,
|
|
.Xr pmf 9 ,
|
|
.Xr xcall 9
|
|
.Rs
|
|
.%A Venkatesh Pallipadi
|
|
.%A Alexey Starikovskiy
|
|
.%T The Ondemand Governor. Past, Present, and Future
|
|
.%I Intel Open Source Technology Center
|
|
.%O Proceedings of the Linux Symposium
|
|
.%D July, 2006
|
|
.%U http://www.kernel.org/doc/ols/2006/ols2006v2-pages-223-238.pdf
|
|
.Re
|
|
.Sh HISTORY
|
|
The
|
|
.Nm
|
|
interface first appeared in
|
|
.Nx 6.0 .
|
|
.Sh AUTHORS
|
|
.An Jukka Ruohonen
|
|
.Aq jruohonen@iki.fi
|
|
.Sh BUGS
|
|
The interface does not support different
|
|
.Dq governors
|
|
and policies.
|