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