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 February 6, 2005 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.Fo cpufreq_levels 39.Fa "device_t dev" 40.Fa "struct cf_level *levels" 41.Fa "int *count" 42.Fc 43.Ft int 44.Fo cpufreq_set 45.Fa "device_t dev" 46.Fa "const struct cf_level *level" 47.Fa "int priority" 48.Fc 49.Ft int 50.Fo cpufreq_get 51.Fa "device_t dev" 52.Fa "struct cf_level *level" 53.Fc 54.Ft int 55.Fo cpufreq_drv_settings 56.Fa "device_t dev" 57.Fa "struct cf_setting *sets" 58.Fa "int *count" 59.Fa "int *type" 60.Fc 61.Ft int 62.Fo cpufreq_drv_set 63.Fa "device_t dev" 64.Fa "const struct cf_setting *set" 65.Fc 66.Ft int 67.Fo cpufreq_drv_get 68.Fa "device_t dev" 69.Fa "struct cf_setting *set" 70.Fc 71.Sh DESCRIPTION 72The 73.Nm 74driver provides a unified kernel and user interface to CPU frequency 75control drivers. 76It combines multiple drivers offering different settings into a single 77interface of all possible levels. 78Users can access this interface directly via 79.Xr sysctl 8 80or by indicating to 81.Xr power_profile 8 82that it should switch settings when the AC line state changes via 83.Xr rc.conf 5 . 84.Sh SYSCTLS 85These settings may be overridden by kernel drivers requesting alternate 86settings. 87If this occurs, the original values will be restored once the condition 88has passed (e.g., the system has cooled sufficiently.) 89If a sysctl can't be set due to an override condition, it will return 90EPERM. 91.Bl -tag -width indent 92.It Va dev.cpu.%d.freq 93Current active CPU frequency in MHz. 94.It Va dev.cpu.%d.freq_levels 95Currently available levels for the CPU frequency and power usage for each. 96Values are in units of MHz and milliwatts. 97.El 98.Sh SUPPORTED DRIVERS 99The following device drivers offer absolute frequency control via the 100.Nm 101interface. 102Usually, only one of these can be active at a time. 103.Pp 104.Bl -tag -compact -width ".Xr acpi_perf 4" 105.It Xr acpi_perf 4 106ACPI CPU performance states 107.It Xr ichss 4 108Intel SpeedStep for ICH 109.El 110.Pp 111.Bl -tag -compact -width ".Xr acpi_throttle 4" 112The following device drivers offer relative frequency control and 113have an additive effect: 114.Pp 115.It Xr acpi_throttle 4 116ACPI CPU throttling 117.El 118.Sh KERNEL INTERFACE 119Kernel components can query and set CPU frequencies through the 120.Nm 121kernel interface. 122This involves obtaining a 123.Nm 124device, calling 125.Fn cpufreq_levels 126to get the currently available frequency levels, 127checking the current level with 128.Fn cpufreq_get , 129and setting a new one from the list with 130.Fn cpufreq_set . 131Each level may actually reference more than one 132.Nm 133driver but kernel components do not need to be aware of this. 134The 135.Vt total_set 136element of 137.Vt struct cf_level 138provides a summary of the frequency and power for this level. 139Unknown or irrelevant values are set to 140.Vt CPUFREQ_VAL_UNKNOWN . 141.Pp 142The 143.Fn cpufreq_levels 144method takes a 145.Nm 146device and an empty array of 147.Ar levels . 148The 149.Ar count 150value should be set to the number of levels available and after the 151function completes, will be set to the actual number of levels returned. 152If there are more levels than 153.Ar count 154will allow, it should return E2BIG. 155.Pp 156The 157.Fn cpufreq_get 158method takes a pointer to space to store a 159.Ar level . 160After successful completion, the output will be the current active level 161and is equal to one of the levels returned by 162.Fn cpufreq_levels . 163.Pp 164The 165.Fn cpufreq_set 166method takes a pointer a 167.Ar level 168and attempts to activate it. 169The 170.Ar priority 171(i.e., CPUFREQ_PRIO_KERN) 172tells 173.Nm 174whether to override previous settings while activating this level. 175If 176.Ar priority 177is higher than the current active level, that level will be saved and 178overridden with the new level. 179If 180.Fn cpufreq_set 181is called with a NULL 182.Ar level , 183the saved level (if any) will be restored. 184If 185.Ar priority 186is lower than the current active level's priority, this method returns 187EPERM. 188.Sh DRIVER INTERFACE 189Kernel drivers offering hardware-specific CPU frequency control export 190their individual settings through the 191.Nm 192driver interface. 193This involves implementing three methods: 194.Fn cpufreq_drv_settings , 195.Fn cpufreq_drv_set , 196and 197.Fn cpufreq_drv_get . 198Additionally, the driver must attach a device as a child of a CPU 199device so that these methods can be called by the 200.Nm 201framework. 202.Pp 203The 204.Fn cpufreq_drv_settings 205method returns an array of currently available settings, each of type 206.Vt struct cf_setting . 207The driver should set unknown or irrelevant values to 208.Vt CPUFREQ_VAL_UNKNOWN . 209All the following elements for each setting should be returned: 210.Bd -literal 211struct cf_setting { 212 int freq; /* CPU clock in Mhz or 100ths of a percent. */ 213 int volts; /* Voltage in mV. */ 214 int power; /* Power consumed in mW. */ 215 int lat; /* Transition latency in us. */ 216 device_t dev; /* Driver providing this setting. */ 217}; 218.Ed 219.Pp 220On entry to this method, 221.Ar count 222contains the number of settings that can be returned. 223On successful completion, the driver sets it to the actual number of 224settings returned. 225If the driver offers more settings than 226.Ar count 227will allow, it should return E2BIG. 228The driver sets 229.Ar type 230to the type of settings it offers, either 231.Vt CPUFREQ_TYPE_ABSOLUTE 232or 233.Vt CPUFREQ_TYPE_RELATIVE . 234.Pp 235The 236.Fn cpufreq_drv_set 237method takes a driver setting and makes it active. 238If the setting is invalid or not currently available, it should return 239EINVAL. 240.Pp 241The 242.Fn cpufreq_drv_get 243method returns the currently-active driver setting. 244The 245.Vt struct cf_setting 246returned must be valid for passing to 247.Fn cpufreq_drv_set , 248including all elements being filled out correctly. 249If the driver cannot infer the current setting 250(even by estimating it with 251.Fn cpu_est_clockrate ) 252then it should set all elements to 253.Vt CPUFREQ_VAL_UNKNOWN . 254.Sh BUGS 255The following drivers have not yet been converted to the 256.Nm 257interface: 258.Xr longrun 4 , 259.Xr p4tcc 4 . 260.Pp 261Priorities and notification of unrequested frequency changes are not 262implemented yet. 263.Pp 264When multiple CPUs offer frequency control, they cannot be set to different 265levels and must all offer the same frequency settings. 266.Sh SEE ALSO 267.Xr acpi 4 , 268.Xr sysctl 8 269.Sh AUTHORS 270.An -nosplit 271.An Nate Lawson 272