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 10, 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.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 power_profile 66that it should switch settings when the AC line state changes via 67.Xr rc.conf 5 . 68.Sh SYSCTLS 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.Bl -tag -width indent 76.It Va dev.cpu.%d.freq 77Current active CPU frequency in MHz. 78.It Va dev.cpu.%d.freq_levels 79Currently available levels for the CPU (frequency/power usage). 80Values are in units of MHz and milliwatts. 81.It Va dev.DEVICE.%d.freq_settings 82Currently available settings for the driver (frequency/power usage). 83Values are in units of MHz and milliwatts. 84This is helpful for understanding which settings are offered by which 85driver for debugging purposes. 86.It Va debug.cpufreq.lowest 87Lowest CPU frequency in MHz to offer to users. 88This setting is also accessible via a tunable with the same name. 89This can be used to disable very low levels that may be unusable on 90some systems. 91.It Va debug.cpufreq.verbose 92Print verbose messages. 93This setting is also accessible via a tunable with the same name. 94.El 95.Sh SUPPORTED DRIVERS 96The following device drivers offer absolute frequency control via the 97.Nm 98interface. 99Usually, only one of these can be active at a time. 100.Pp 101.Bl -tag -compact -width ".Pa acpi_perf" 102.It Pa acpi_perf 103ACPI CPU performance states 104.It Pa est 105Intel Enhanced SpeedStep 106.It Pa ichss 107Intel SpeedStep for ICH 108.It Pa powernow 109AMD PowerNow! for K7 and K8 110.El 111.Pp 112The following device drivers offer relative frequency control and 113have an additive effect: 114.Pp 115.Bl -tag -compact -width ".Pa acpi_throttle" 116.It Pa acpi_throttle 117ACPI CPU throttling 118.It Pa p4tcc 119Pentium 4 Thermal Control Circuitry 120.El 121.Sh KERNEL INTERFACE 122Kernel components can query and set CPU frequencies through the 123.Nm 124kernel interface. 125This involves obtaining a 126.Nm 127device, calling 128.Fn cpufreq_levels 129to get the currently available frequency levels, 130checking the current level with 131.Fn cpufreq_get , 132and setting a new one from the list with 133.Fn cpufreq_set . 134Each level may actually reference more than one 135.Nm 136driver but kernel components do not need to be aware of this. 137The 138.Va total_set 139element of 140.Vt "struct cf_level" 141provides a summary of the frequency and power for this level. 142Unknown or irrelevant values are set to 143.Dv CPUFREQ_VAL_UNKNOWN . 144.Pp 145The 146.Fn cpufreq_levels 147method takes a 148.Nm 149device and an empty array of 150.Fa levels . 151The 152.Fa count 153value should be set to the number of levels available and after the 154function completes, will be set to the actual number of levels returned. 155If there are more levels than 156.Fa count 157will allow, it should return 158.Er E2BIG . 159.Pp 160The 161.Fn cpufreq_get 162method takes a pointer to space to store a 163.Fa level . 164After successful completion, the output will be the current active level 165and is equal to one of the levels returned by 166.Fn cpufreq_levels . 167.Pp 168The 169.Fn cpufreq_set 170method takes a pointer a 171.Fa level 172and attempts to activate it. 173The 174.Fa priority 175(i.e., 176.Dv CPUFREQ_PRIO_KERN ) 177tells 178.Nm 179whether to override previous settings while activating this level. 180If 181.Fa priority 182is higher than the current active level, that level will be saved and 183overridden with the new level. 184If a level is already saved, the new level is set without overwriting 185the older saved level. 186If 187.Fn cpufreq_set 188is called with a 189.Dv NULL 190.Fa level , 191the saved level will be restored. 192If there is no saved level, 193.Fn cpufreq_set 194will return 195.Er ENXIO . 196If 197.Fa priority 198is lower than the current active level's priority, this method returns 199.Er EPERM . 200.Sh DRIVER INTERFACE 201Kernel drivers offering hardware-specific CPU frequency control export 202their individual settings through the 203.Nm 204driver interface. 205This involves implementing these methods: 206.Fn cpufreq_drv_settings , 207.Fn cpufreq_drv_type , 208.Fn cpufreq_drv_set , 209and 210.Fn cpufreq_drv_get . 211Additionally, the driver must attach a device as a child of a CPU 212device so that these methods can be called by the 213.Nm 214framework. 215.Pp 216The 217.Fn cpufreq_drv_settings 218method returns an array of currently available settings, each of type 219.Vt "struct cf_setting" . 220The driver should set unknown or irrelevant values to 221.Dv CPUFREQ_VAL_UNKNOWN . 222All the following elements for each setting should be returned: 223.Bd -literal 224struct cf_setting { 225 int freq; /* CPU clock in Mhz or 100ths of a percent. */ 226 int volts; /* Voltage in mV. */ 227 int power; /* Power consumed in mW. */ 228 int lat; /* Transition latency in us. */ 229 device_t dev; /* Driver providing this setting. */ 230}; 231.Ed 232.Pp 233On entry to this method, 234.Fa count 235contains the number of settings that can be returned. 236On successful completion, the driver sets it to the actual number of 237settings returned. 238If the driver offers more settings than 239.Fa count 240will allow, it should return 241.Er E2BIG . 242.Pp 243The 244.Fn cpufreq_drv_type 245method indicates the type of settings it offers, either 246.Dv CPUFREQ_TYPE_ABSOLUTE 247or 248.Dv CPUFREQ_TYPE_RELATIVE . 249Additionally, the driver may set the 250.Dv CPUFREQ_FLAG_INFO_ONLY 251flag if the settings it provides are information for other drivers only 252and cannot be passed to 253.Fn cpufreq_drv_set 254to activate them. 255.Pp 256The 257.Fn cpufreq_drv_set 258method takes a driver setting and makes it active. 259If the setting is invalid or not currently available, it should return 260.Er EINVAL . 261.Pp 262The 263.Fn cpufreq_drv_get 264method returns the currently-active driver setting. 265The 266.Vt "struct cf_setting" 267returned must be valid for passing to 268.Fn cpufreq_drv_set , 269including all elements being filled out correctly. 270If the driver cannot infer the current setting 271(even by estimating it with 272.Fn cpu_est_clockrate ) 273then it should set all elements to 274.Dv CPUFREQ_VAL_UNKNOWN . 275.Sh SEE ALSO 276.Xr acpi 4 , 277.Xr sysctl 8 278.Sh AUTHORS 279.An Nate Lawson 280.An Bruno Ducrot 281contributed the 282.Pa powernow 283driver. 284.Sh BUGS 285The following drivers have not yet been converted to the 286.Nm 287interface: 288.Xr longrun 4 . 289.Pp 290Notification of CPU and bus frequency changes is not implemented yet. 291.Pp 292When multiple CPUs offer frequency control, they cannot be set to different 293levels and must all offer the same frequency settings. 294