summaryrefslogtreecommitdiff
path: root/static/freebsd/man4/cpufreq.4 3.html
blob: c2b02a7d8b39c07a291232d7baf78ec4dc165ad4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
<table class="head">
  <tr>
    <td class="head-ltitle">CPUFREQ(4)</td>
    <td class="head-vol">Device Drivers Manual</td>
    <td class="head-rtitle">CPUFREQ(4)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">cpufreq</code> &#x2014; <span class="Nd">CPU
    frequency control framework</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="Cd">device cpufreq</code></p>
<p class="Pp">
  <br/>
  <code class="In">#include &lt;<a class="In">sys/cpu.h</a>&gt;</code></p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">cpufreq_levels</code>(<var class="Fa" style="white-space: nowrap;">device_t
    dev</var>, <var class="Fa" style="white-space: nowrap;">struct cf_level
    *levels</var>, <var class="Fa" style="white-space: nowrap;">int
    *count</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">cpufreq_set</code>(<var class="Fa" style="white-space: nowrap;">device_t
    dev</var>, <var class="Fa" style="white-space: nowrap;">const struct
    cf_level *level</var>, <var class="Fa" style="white-space: nowrap;">int
    priority</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">cpufreq_get</code>(<var class="Fa" style="white-space: nowrap;">device_t
    dev</var>, <var class="Fa" style="white-space: nowrap;">struct cf_level
    *level</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">cpufreq_drv_settings</code>(<var class="Fa">device_t
    dev</var>, <var class="Fa">struct cf_setting *sets</var>,
    <var class="Fa">int *count</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">cpufreq_drv_type</code>(<var class="Fa" style="white-space: nowrap;">device_t
    dev</var>, <var class="Fa" style="white-space: nowrap;">int
  *type</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">cpufreq_drv_set</code>(<var class="Fa" style="white-space: nowrap;">device_t
    dev</var>, <var class="Fa" style="white-space: nowrap;">const struct
    cf_setting *set</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">cpufreq_drv_get</code>(<var class="Fa" style="white-space: nowrap;">device_t
    dev</var>, <var class="Fa" style="white-space: nowrap;">struct cf_setting
    *set</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">cpufreq</code> driver provides a unified
    kernel and user interface to CPU frequency control drivers. It combines
    multiple drivers offering different settings into a single interface of all
    possible levels. Users can access this interface directly via
    <a class="Xr">sysctl(8)</a> or by indicating to
    <span class="Pa">/etc/rc.d/power_profile</span> that it should switch
    settings when the AC line state changes via
  <a class="Xr">rc.conf(5)</a>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYSCTL_VARIABLES"><a class="permalink" href="#SYSCTL_VARIABLES">SYSCTL
  VARIABLES</a></h1>
<p class="Pp">These settings may be overridden by kernel drivers requesting
    alternate settings. If this occurs, the original values will be restored
    once the condition has passed (e.g., the system has cooled sufficiently). If
    a sysctl cannot be set due to an override condition, it will return
    <code class="Er">EPERM</code>.</p>
<p class="Pp">The frequency cannot be changed if TSC is in use as the
    timecounter and the hardware does not support invariant TSC. This is because
    the timecounter system needs to use a source that has a constant rate. (On
    invariant TSC hardware, the TSC runs at the P0 rate regardless of the
    configured P-state.) Modern hardware mostly has invariant TSC. The
    timecounter source can be changed with the
    <span class="Pa">kern.timecounter.hardware</span> sysctl. Available modes
    are in <span class="Pa">kern.timecounter.choice</span> sysctl entry.</p>
<dl class="Bl-tag">
  <dt id="dev.cpu._d.freq"><var class="Va">dev.cpu.%d.freq</var></dt>
  <dd>Current active CPU frequency in MHz.</dd>
  <dt id="dev.cpu._d.freq_driver"><var class="Va">dev.cpu.%d.freq_driver</var></dt>
  <dd>The specific <code class="Nm">cpufreq</code> driver used by this cpu.</dd>
  <dt id="dev.cpu._d.freq_levels"><var class="Va">dev.cpu.%d.freq_levels</var></dt>
  <dd>Currently available levels for the CPU (frequency/power usage). Values are
      in units of MHz and milliwatts.</dd>
  <dt id="dev.DEVICE._d.freq_settings"><var class="Va">dev.DEVICE.%d.freq_settings</var></dt>
  <dd>Currently available settings for the driver (frequency/power usage).
      Values are in units of MHz and milliwatts. This is helpful for
      understanding which settings are offered by which driver for debugging
      purposes.</dd>
  <dt id="debug.cpufreq.lowest"><var class="Va">debug.cpufreq.lowest</var></dt>
  <dd>Lowest CPU frequency in MHz to offer to users. This setting is also
      accessible via a tunable with the same name. This can be used to disable
      very low levels that may be unusable on some systems.</dd>
  <dt id="debug.cpufreq.verbose"><var class="Va">debug.cpufreq.verbose</var></dt>
  <dd>Print verbose messages. This setting is also accessible via a tunable with
      the same name.</dd>
  <dt id="debug.hwpstate_pstate_limit"><var class="Va">debug.hwpstate_pstate_limit</var></dt>
  <dd>If enabled, the AMD hwpstate driver limits administrative control of
      P-states (including by <a class="Xr">powerd(8)</a>) to the value in the
      0xc0010061 MSR, known as &quot;PStateCurLim[CurPstateLimit].&quot; It is
      disabled (0) by default. On some hardware, the limit register seems to
      simply follow the configured P-state, which results in the inability to
      ever raise the P-state back to P0 from a reduced frequency state.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="SUPPORTED_DRIVERS"><a class="permalink" href="#SUPPORTED_DRIVERS">SUPPORTED
  DRIVERS</a></h1>
<p class="Pp">The following device drivers offer absolute frequency control via
    the <code class="Nm">cpufreq</code> interface. Usually, only one of these
    can be active at a time.</p>
<p class="Pp"></p>
<dl class="Bl-tag Bl-compact">
  <dt>acpi_perf</dt>
  <dd>ACPI CPU performance states</dd>
  <dt><a class="Xr">est(4)</a></dt>
  <dd>Intel Enhanced SpeedStep</dd>
  <dt>hwpstate</dt>
  <dd>AMD Cool'n'Quiet2 used in K10 through Family 17h</dd>
  <dt><a class="Xr">hwpstate_intel(4)</a></dt>
  <dd>Intel SpeedShift driver</dd>
  <dt>ichss</dt>
  <dd>Intel SpeedStep for ICH</dd>
  <dt>powernow</dt>
  <dd>AMD PowerNow! and Cool'n'Quiet for K7 and K8</dd>
  <dt>smist</dt>
  <dd>Intel SMI-based SpeedStep for PIIX4</dd>
</dl>
<p class="Pp">The following device drivers offer relative frequency control and
    have an additive effect:</p>
<p class="Pp"></p>
<dl class="Bl-tag Bl-compact">
  <dt>acpi_throttle</dt>
  <dd>ACPI CPU throttling</dd>
  <dt>p4tcc</dt>
  <dd>Pentium 4 Thermal Control Circuitry</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="KERNEL_INTERFACE"><a class="permalink" href="#KERNEL_INTERFACE">KERNEL
  INTERFACE</a></h1>
<p class="Pp">Kernel components can query and set CPU frequencies through the
    <code class="Nm">cpufreq</code> kernel interface. This involves obtaining a
    <code class="Nm">cpufreq</code> device, calling
    <a class="permalink" href="#cpufreq_levels"><code class="Fn" id="cpufreq_levels">cpufreq_levels</code></a>()
    to get the currently available frequency levels, checking the current level
    with <code class="Fn">cpufreq_get</code>(), and setting a new one from the
    list with <code class="Fn">cpufreq_set</code>(). Each level may actually
    reference more than one <code class="Nm">cpufreq</code> driver but kernel
    components do not need to be aware of this. The
    <var class="Va">total_set</var> element of <var class="Vt">struct
    cf_level</var> provides a summary of the frequency and power for this level.
    Unknown or irrelevant values are set to
    <code class="Dv">CPUFREQ_VAL_UNKNOWN</code>.</p>
<p class="Pp" id="cpufreq_levels~2">The
    <a class="permalink" href="#cpufreq_levels~2"><code class="Fn">cpufreq_levels</code></a>()
    method takes a <code class="Nm">cpufreq</code> device and an empty array of
    <var class="Fa">levels</var>. The <var class="Fa">count</var> value should
    be set to the number of levels available and after the function completes,
    will be set to the actual number of levels returned. If there are more
    levels than <var class="Fa">count</var> will allow, it should return
    <code class="Er">E2BIG</code>.</p>
<p class="Pp" id="cpufreq_get">The
    <a class="permalink" href="#cpufreq_get"><code class="Fn">cpufreq_get</code></a>()
    method takes a pointer to space to store a <var class="Fa">level</var>.
    After successful completion, the output will be the current active level and
    is equal to one of the levels returned by
    <code class="Fn">cpufreq_levels</code>().</p>
<p class="Pp" id="cpufreq_set">The
    <a class="permalink" href="#cpufreq_set"><code class="Fn">cpufreq_set</code></a>()
    method takes a pointer a <var class="Fa">level</var> and attempts to
    activate it. The <var class="Fa">priority</var> (i.e.,
    <code class="Dv">CPUFREQ_PRIO_KERN</code>) tells
    <code class="Nm">cpufreq</code> whether to override previous settings while
    activating this level. If <var class="Fa">priority</var> is higher than the
    current active level, that level will be saved and overridden with the new
    level. If a level is already saved, the new level is set without overwriting
    the older saved level. If <code class="Fn">cpufreq_set</code>() is called
    with a <code class="Dv">NULL</code> <var class="Fa">level</var>, the saved
    level will be restored. If there is no saved level,
    <code class="Fn">cpufreq_set</code>() will return
    <code class="Er">ENXIO</code>. If <var class="Fa">priority</var> is lower
    than the current active level's priority, this method returns
    <code class="Er">EPERM</code>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DRIVER_INTERFACE"><a class="permalink" href="#DRIVER_INTERFACE">DRIVER
  INTERFACE</a></h1>
<p class="Pp">Kernel drivers offering hardware-specific CPU frequency control
    export their individual settings through the <code class="Nm">cpufreq</code>
    driver interface. This involves implementing these methods:
    <code class="Fn">cpufreq_drv_settings</code>(),
    <code class="Fn">cpufreq_drv_type</code>(),
    <code class="Fn">cpufreq_drv_set</code>(), and
    <code class="Fn">cpufreq_drv_get</code>(). Additionally, the driver must
    attach a device as a child of a CPU device so that these methods can be
    called by the <code class="Nm">cpufreq</code> framework.</p>
<p class="Pp" id="cpufreq_drv_settings">The
    <a class="permalink" href="#cpufreq_drv_settings"><code class="Fn">cpufreq_drv_settings</code></a>()
    method returns an array of currently available settings, each of type
    <var class="Vt">struct cf_setting</var>. The driver should set unknown or
    irrelevant values to <code class="Dv">CPUFREQ_VAL_UNKNOWN</code>. All the
    following elements for each setting should be returned:</p>
<div class="Bd Pp Li">
<pre>struct cf_setting {
	int	freq;	/* CPU clock in MHz or 100ths of a percent. */
	int	volts;	/* Voltage in mV. */
	int	power;	/* Power consumed in mW. */
	int	lat;	/* Transition latency in us. */
	device_t dev;	/* Driver providing this setting. */
};</pre>
</div>
<p class="Pp">On entry to this method, <var class="Fa">count</var> contains the
    number of settings that can be returned. On successful completion, the
    driver sets it to the actual number of settings returned. If the driver
    offers more settings than <var class="Fa">count</var> will allow, it should
    return <code class="Er">E2BIG</code>.</p>
<p class="Pp" id="cpufreq_drv_type">The
    <a class="permalink" href="#cpufreq_drv_type"><code class="Fn">cpufreq_drv_type</code></a>()
    method indicates the type of settings it offers, either
    <code class="Dv">CPUFREQ_TYPE_ABSOLUTE</code> or
    <code class="Dv">CPUFREQ_TYPE_RELATIVE</code>. Additionally, the driver may
    set the <code class="Dv">CPUFREQ_FLAG_INFO_ONLY</code> flag if the settings
    it provides are information for other drivers only and cannot be passed to
    <code class="Fn">cpufreq_drv_set</code>() to activate them.</p>
<p class="Pp" id="cpufreq_drv_set">The
    <a class="permalink" href="#cpufreq_drv_set"><code class="Fn">cpufreq_drv_set</code></a>()
    method takes a driver setting and makes it active. If the setting is invalid
    or not currently available, it should return
  <code class="Er">EINVAL</code>.</p>
<p class="Pp" id="cpufreq_drv_get">The
    <a class="permalink" href="#cpufreq_drv_get"><code class="Fn">cpufreq_drv_get</code></a>()
    method returns the currently-active driver setting. The
    <var class="Vt">struct cf_setting</var> returned must be valid for passing
    to <code class="Fn">cpufreq_drv_set</code>(), including all elements being
    filled out correctly. If the driver cannot infer the current setting (even
    by estimating it with
    <a class="permalink" href="#cpu_est_clockrate"><code class="Fn" id="cpu_est_clockrate">cpu_est_clockrate</code></a>())
    then it should set all elements to
    <code class="Dv">CPUFREQ_VAL_UNKNOWN</code>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
  ALSO</a></h1>
<p class="Pp"><a class="Xr">acpi(4)</a>, <a class="Xr">est(4)</a>,
    <a class="Xr">timecounters(4)</a>, <a class="Xr">powerd(8)</a>,
    <a class="Xr">sysctl(8)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp"><span class="An">Nate Lawson</span>
  <br/>
  <span class="An">Bruno Ducrot</span> contributed the
    <span class="Pa">powernow</span> driver.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="BUGS"><a class="permalink" href="#BUGS">BUGS</a></h1>
<p class="Pp">The following drivers have not yet been converted to the
    <code class="Nm">cpufreq</code> interface: <a class="Xr">longrun(4)</a>.</p>
<p class="Pp">Notification of CPU and bus frequency changes is not implemented
    yet.</p>
<p class="Pp">When multiple CPUs offer frequency control, they cannot be set to
    different levels and must all offer the same frequency settings.</p>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">April 4, 2022</td>
    <td class="foot-os">FreeBSD 15.0</td>
  </tr>
</table>