xref: /freebsd/share/man/man4/cpufreq.4 (revision b0d29bc47dba79f6f38e67eabadfb4b32ffd9390)
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 31, 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 and the
77hardware does not support invariant TSC.
78This is because the timecounter system needs to use a source that has a
79constant rate.
80(On invariant TSC hardware, the TSC runs at the P0 rate regardless of the
81configured P-state.)
82Modern hardware mostly has invariant TSC.
83The timecounter source can be changed with the
84.Pa kern.timecounter.hardware
85sysctl.
86Available modes are in
87.Pa kern.timecounter.choice
88sysctl entry.
89.Bl -tag -width indent
90.It Va dev.cpu.%d.freq
91Current active CPU frequency in MHz.
92.It Va dev.cpu.%d.freq_driver
93The specific
94.Nm
95driver used by this cpu.
96.It Va dev.cpu.%d.freq_levels
97Currently available levels for the CPU (frequency/power usage).
98Values are in units of MHz and milliwatts.
99.It Va dev.DEVICE.%d.freq_settings
100Currently available settings for the driver (frequency/power usage).
101Values are in units of MHz and milliwatts.
102This is helpful for understanding which settings are offered by which
103driver for debugging purposes.
104.It Va debug.cpufreq.lowest
105Lowest CPU frequency in MHz to offer to users.
106This setting is also accessible via a tunable with the same name.
107This can be used to disable very low levels that may be unusable on
108some systems.
109.It Va debug.cpufreq.verbose
110Print verbose messages.
111This setting is also accessible via a tunable with the same name.
112.It Va debug.hwpstate_pstate_limit
113If enabled, the AMD hwpstate driver limits administrative control of P-states
114(including by
115.Xr powerd 8 )
116to the value in the 0xc0010061 MSR, known as "PStateCurLim[CurPstateLimit]."
117It is disabled (0) by default.
118On some hardware, the limit register seems to simply follow the configured
119P-state, which results in the inability to ever raise the P-state back to P0
120from a reduced frequency state.
121.El
122.Sh SUPPORTED DRIVERS
123The following device drivers offer absolute frequency control via the
124.Nm
125interface.
126Usually, only one of these can be active at a time.
127.Pp
128.Bl -tag -compact -width ".Pa hwpstate_intel"
129.It Pa acpi_perf
130ACPI CPU performance states
131.It Pa est
132Intel Enhanced SpeedStep
133.It Pa hwpstate
134AMD Cool'n'Quiet2 used in K10 through Family 17h
135.It Pa hwpstate_intel
136Intel SpeedShift driver
137.It Pa ichss
138Intel SpeedStep for ICH
139.It Pa powernow
140AMD PowerNow!\& and Cool'n'Quiet for K7 and K8
141.It Pa smist
142Intel SMI-based SpeedStep for PIIX4
143.El
144.Pp
145The following device drivers offer relative frequency control and
146have an additive effect:
147.Pp
148.Bl -tag -compact -width ".Pa acpi_throttle"
149.It Pa acpi_throttle
150ACPI CPU throttling
151.It Pa p4tcc
152Pentium 4 Thermal Control Circuitry
153.El
154.Sh KERNEL INTERFACE
155Kernel components can query and set CPU frequencies through the
156.Nm
157kernel interface.
158This involves obtaining a
159.Nm
160device, calling
161.Fn cpufreq_levels
162to get the currently available frequency levels,
163checking the current level with
164.Fn cpufreq_get ,
165and setting a new one from the list with
166.Fn cpufreq_set .
167Each level may actually reference more than one
168.Nm
169driver but kernel components do not need to be aware of this.
170The
171.Va total_set
172element of
173.Vt "struct cf_level"
174provides a summary of the frequency and power for this level.
175Unknown or irrelevant values are set to
176.Dv CPUFREQ_VAL_UNKNOWN .
177.Pp
178The
179.Fn cpufreq_levels
180method takes a
181.Nm
182device and an empty array of
183.Fa levels .
184The
185.Fa count
186value should be set to the number of levels available and after the
187function completes, will be set to the actual number of levels returned.
188If there are more levels than
189.Fa count
190will allow, it should return
191.Er E2BIG .
192.Pp
193The
194.Fn cpufreq_get
195method takes a pointer to space to store a
196.Fa level .
197After successful completion, the output will be the current active level
198and is equal to one of the levels returned by
199.Fn cpufreq_levels .
200.Pp
201The
202.Fn cpufreq_set
203method takes a pointer a
204.Fa level
205and attempts to activate it.
206The
207.Fa priority
208(i.e.,
209.Dv CPUFREQ_PRIO_KERN )
210tells
211.Nm
212whether to override previous settings while activating this level.
213If
214.Fa priority
215is higher than the current active level, that level will be saved and
216overridden with the new level.
217If a level is already saved, the new level is set without overwriting
218the older saved level.
219If
220.Fn cpufreq_set
221is called with a
222.Dv NULL
223.Fa level ,
224the saved level will be restored.
225If there is no saved level,
226.Fn cpufreq_set
227will return
228.Er ENXIO .
229If
230.Fa priority
231is lower than the current active level's priority, this method returns
232.Er EPERM .
233.Sh DRIVER INTERFACE
234Kernel drivers offering hardware-specific CPU frequency control export
235their individual settings through the
236.Nm
237driver interface.
238This involves implementing these methods:
239.Fn cpufreq_drv_settings ,
240.Fn cpufreq_drv_type ,
241.Fn cpufreq_drv_set ,
242and
243.Fn cpufreq_drv_get .
244Additionally, the driver must attach a device as a child of a CPU
245device so that these methods can be called by the
246.Nm
247framework.
248.Pp
249The
250.Fn cpufreq_drv_settings
251method returns an array of currently available settings, each of type
252.Vt "struct cf_setting" .
253The driver should set unknown or irrelevant values to
254.Dv CPUFREQ_VAL_UNKNOWN .
255All the following elements for each setting should be returned:
256.Bd -literal
257struct cf_setting {
258	int	freq;	/* CPU clock in MHz or 100ths of a percent. */
259	int	volts;	/* Voltage in mV. */
260	int	power;	/* Power consumed in mW. */
261	int	lat;	/* Transition latency in us. */
262	device_t dev;	/* Driver providing this setting. */
263};
264.Ed
265.Pp
266On entry to this method,
267.Fa count
268contains the number of settings that can be returned.
269On successful completion, the driver sets it to the actual number of
270settings returned.
271If the driver offers more settings than
272.Fa count
273will allow, it should return
274.Er E2BIG .
275.Pp
276The
277.Fn cpufreq_drv_type
278method indicates the type of settings it offers, either
279.Dv CPUFREQ_TYPE_ABSOLUTE
280or
281.Dv CPUFREQ_TYPE_RELATIVE .
282Additionally, the driver may set the
283.Dv CPUFREQ_FLAG_INFO_ONLY
284flag if the settings it provides are information for other drivers only
285and cannot be passed to
286.Fn cpufreq_drv_set
287to activate them.
288.Pp
289The
290.Fn cpufreq_drv_set
291method takes a driver setting and makes it active.
292If the setting is invalid or not currently available, it should return
293.Er EINVAL .
294.Pp
295The
296.Fn cpufreq_drv_get
297method returns the currently-active driver setting.
298The
299.Vt "struct cf_setting"
300returned must be valid for passing to
301.Fn cpufreq_drv_set ,
302including all elements being filled out correctly.
303If the driver cannot infer the current setting
304(even by estimating it with
305.Fn cpu_est_clockrate )
306then it should set all elements to
307.Dv CPUFREQ_VAL_UNKNOWN .
308.Sh SEE ALSO
309.Xr acpi 4 ,
310.Xr est 4 ,
311.Xr timecounters 4 ,
312.Xr powerd 8 ,
313.Xr sysctl 8
314.Sh AUTHORS
315.An Nate Lawson
316.An Bruno Ducrot
317contributed the
318.Pa powernow
319driver.
320.Sh BUGS
321The following drivers have not yet been converted to the
322.Nm
323interface:
324.Xr longrun 4 .
325.Pp
326Notification of CPU and bus frequency changes is not implemented yet.
327.Pp
328When multiple CPUs offer frequency control, they cannot be set to different
329levels and must all offer the same frequency settings.
330