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