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