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