xref: /freebsd/share/man/man4/cpufreq.4 (revision 6966ac055c3b7a39266fb982493330df7a097997)
1.\" Copyright (c) 2005 Nate Lawson
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd January 22, 2020
28.Dt CPUFREQ 4
29.Os
30.Sh NAME
31.Nm cpufreq
32.Nd CPU frequency control framework
33.Sh SYNOPSIS
34.Cd "device cpufreq"
35.Pp
36.In sys/cpu.h
37.Ft int
38.Fn cpufreq_levels "device_t dev" "struct cf_level *levels" "int *count"
39.Ft int
40.Fn cpufreq_set "device_t dev" "const struct cf_level *level" "int priority"
41.Ft int
42.Fn cpufreq_get "device_t dev" "struct cf_level *level"
43.Ft int
44.Fo cpufreq_drv_settings
45.Fa "device_t dev"
46.Fa "struct cf_setting *sets"
47.Fa "int *count"
48.Fc
49.Ft int
50.Fn cpufreq_drv_type "device_t dev" "int *type"
51.Ft int
52.Fn cpufreq_drv_set "device_t dev" "const struct cf_setting *set"
53.Ft int
54.Fn cpufreq_drv_get "device_t dev" "struct cf_setting *set"
55.Sh DESCRIPTION
56The
57.Nm
58driver provides a unified kernel and user interface to CPU frequency
59control drivers.
60It combines multiple drivers offering different settings into a single
61interface of all possible levels.
62Users can access this interface directly via
63.Xr sysctl 8
64or by indicating to
65.Pa /etc/rc.d/power_profile
66that it should switch settings when the AC line state changes via
67.Xr rc.conf 5 .
68.Sh SYSCTL VARIABLES
69These settings may be overridden by kernel drivers requesting alternate
70settings.
71If this occurs, the original values will be restored once the condition
72has passed (e.g., the system has cooled sufficiently).
73If a sysctl cannot be set due to an override condition, it will return
74.Er EPERM .
75.Pp
76The frequency cannot be changed if TSC is in use as the timecounter.
77This is because the timecounter system needs to use a source that has a
78constant rate.
79The timecounter source can be changed with the
80.Pa kern.timecounter.hardware
81sysctl.
82Available modes are in
83.Pa kern.timecounter.choice
84sysctl entry.
85.Bl -tag -width indent
86.It Va dev.cpu.%d.freq
87Current active CPU frequency in MHz.
88.It Va dev.cpu.%d.freq_driver
89The specific
90.Nm
91driver used by this cpu.
92.It Va dev.cpu.%d.freq_levels
93Currently available levels for the CPU (frequency/power usage).
94Values are in units of MHz and milliwatts.
95.It Va dev.DEVICE.%d.freq_settings
96Currently available settings for the driver (frequency/power usage).
97Values are in units of MHz and milliwatts.
98This is helpful for understanding which settings are offered by which
99driver for debugging purposes.
100.It Va debug.cpufreq.lowest
101Lowest CPU frequency in MHz to offer to users.
102This setting is also accessible via a tunable with the same name.
103This can be used to disable very low levels that may be unusable on
104some systems.
105.It Va debug.cpufreq.verbose
106Print verbose messages.
107This setting is also accessible via a tunable with the same name.
108.El
109.Sh SUPPORTED DRIVERS
110The following device drivers offer absolute frequency control via the
111.Nm
112interface.
113Usually, only one of these can be active at a time.
114.Pp
115.Bl -tag -compact -width ".Pa acpi_perf"
116.It Pa acpi_perf
117ACPI CPU performance states
118.It Pa est
119Intel Enhanced SpeedStep
120.It Pa ichss
121Intel SpeedStep for ICH
122.It Pa powernow
123AMD PowerNow!\& and Cool'n'Quiet for K7 and K8
124.It Pa smist
125Intel SMI-based SpeedStep for PIIX4
126.El
127.Pp
128The following device drivers offer relative frequency control and
129have an additive effect:
130.Pp
131.Bl -tag -compact -width ".Pa acpi_throttle"
132.It Pa acpi_throttle
133ACPI CPU throttling
134.It Pa p4tcc
135Pentium 4 Thermal Control Circuitry
136.El
137.Sh KERNEL INTERFACE
138Kernel components can query and set CPU frequencies through the
139.Nm
140kernel interface.
141This involves obtaining a
142.Nm
143device, calling
144.Fn cpufreq_levels
145to get the currently available frequency levels,
146checking the current level with
147.Fn cpufreq_get ,
148and setting a new one from the list with
149.Fn cpufreq_set .
150Each level may actually reference more than one
151.Nm
152driver but kernel components do not need to be aware of this.
153The
154.Va total_set
155element of
156.Vt "struct cf_level"
157provides a summary of the frequency and power for this level.
158Unknown or irrelevant values are set to
159.Dv CPUFREQ_VAL_UNKNOWN .
160.Pp
161The
162.Fn cpufreq_levels
163method takes a
164.Nm
165device and an empty array of
166.Fa levels .
167The
168.Fa count
169value should be set to the number of levels available and after the
170function completes, will be set to the actual number of levels returned.
171If there are more levels than
172.Fa count
173will allow, it should return
174.Er E2BIG .
175.Pp
176The
177.Fn cpufreq_get
178method takes a pointer to space to store a
179.Fa level .
180After successful completion, the output will be the current active level
181and is equal to one of the levels returned by
182.Fn cpufreq_levels .
183.Pp
184The
185.Fn cpufreq_set
186method takes a pointer a
187.Fa level
188and attempts to activate it.
189The
190.Fa priority
191(i.e.,
192.Dv CPUFREQ_PRIO_KERN )
193tells
194.Nm
195whether to override previous settings while activating this level.
196If
197.Fa priority
198is higher than the current active level, that level will be saved and
199overridden with the new level.
200If a level is already saved, the new level is set without overwriting
201the older saved level.
202If
203.Fn cpufreq_set
204is called with a
205.Dv NULL
206.Fa level ,
207the saved level will be restored.
208If there is no saved level,
209.Fn cpufreq_set
210will return
211.Er ENXIO .
212If
213.Fa priority
214is lower than the current active level's priority, this method returns
215.Er EPERM .
216.Sh DRIVER INTERFACE
217Kernel drivers offering hardware-specific CPU frequency control export
218their individual settings through the
219.Nm
220driver interface.
221This involves implementing these methods:
222.Fn cpufreq_drv_settings ,
223.Fn cpufreq_drv_type ,
224.Fn cpufreq_drv_set ,
225and
226.Fn cpufreq_drv_get .
227Additionally, the driver must attach a device as a child of a CPU
228device so that these methods can be called by the
229.Nm
230framework.
231.Pp
232The
233.Fn cpufreq_drv_settings
234method returns an array of currently available settings, each of type
235.Vt "struct cf_setting" .
236The driver should set unknown or irrelevant values to
237.Dv CPUFREQ_VAL_UNKNOWN .
238All the following elements for each setting should be returned:
239.Bd -literal
240struct cf_setting {
241	int	freq;	/* CPU clock in MHz or 100ths of a percent. */
242	int	volts;	/* Voltage in mV. */
243	int	power;	/* Power consumed in mW. */
244	int	lat;	/* Transition latency in us. */
245	device_t dev;	/* Driver providing this setting. */
246};
247.Ed
248.Pp
249On entry to this method,
250.Fa count
251contains the number of settings that can be returned.
252On successful completion, the driver sets it to the actual number of
253settings returned.
254If the driver offers more settings than
255.Fa count
256will allow, it should return
257.Er E2BIG .
258.Pp
259The
260.Fn cpufreq_drv_type
261method indicates the type of settings it offers, either
262.Dv CPUFREQ_TYPE_ABSOLUTE
263or
264.Dv CPUFREQ_TYPE_RELATIVE .
265Additionally, the driver may set the
266.Dv CPUFREQ_FLAG_INFO_ONLY
267flag if the settings it provides are information for other drivers only
268and cannot be passed to
269.Fn cpufreq_drv_set
270to activate them.
271.Pp
272The
273.Fn cpufreq_drv_set
274method takes a driver setting and makes it active.
275If the setting is invalid or not currently available, it should return
276.Er EINVAL .
277.Pp
278The
279.Fn cpufreq_drv_get
280method returns the currently-active driver setting.
281The
282.Vt "struct cf_setting"
283returned must be valid for passing to
284.Fn cpufreq_drv_set ,
285including all elements being filled out correctly.
286If the driver cannot infer the current setting
287(even by estimating it with
288.Fn cpu_est_clockrate )
289then it should set all elements to
290.Dv CPUFREQ_VAL_UNKNOWN .
291.Sh SEE ALSO
292.Xr acpi 4 ,
293.Xr est 4 ,
294.Xr timecounters 4 ,
295.Xr powerd 8 ,
296.Xr sysctl 8
297.Sh AUTHORS
298.An Nate Lawson
299.An Bruno Ducrot
300contributed the
301.Pa powernow
302driver.
303.Sh BUGS
304The following drivers have not yet been converted to the
305.Nm
306interface:
307.Xr longrun 4 .
308.Pp
309Notification of CPU and bus frequency changes is not implemented yet.
310.Pp
311When multiple CPUs offer frequency control, they cannot be set to different
312levels and must all offer the same frequency settings.
313