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