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 April 4, 2022 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 "hwpstate_intel(4)" 129.It acpi_perf 130ACPI CPU performance states 131.It Xr est 4 132Intel Enhanced SpeedStep 133.It hwpstate 134AMD Cool'n'Quiet2 used in K10 through Family 17h 135.It Xr hwpstate_intel 4 136Intel SpeedShift driver 137.It ichss 138Intel SpeedStep for ICH 139.It powernow 140AMD PowerNow!\& and Cool'n'Quiet for K7 and K8 141.It 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 "acpi_throttle" 149.It acpi_throttle 150ACPI CPU throttling 151.It 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