Deleted Added
full compact
est.c (148583) est.c (155996)
1/*-
2 * Copyright (c) 2004 Colin Percival
3 * Copyright (c) 2005 Nate Lawson
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted providing that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2004 Colin Percival
3 * Copyright (c) 2005 Nate Lawson
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted providing that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/i386/cpufreq/est.c 148583 2005-07-31 06:42:27Z cperciva $");
29__FBSDID("$FreeBSD: head/sys/i386/cpufreq/est.c 155996 2006-02-25 04:55:38Z cperciva $");
30
31#include <sys/param.h>
32#include <sys/bus.h>
33#include <sys/cpu.h>
34#include <sys/kernel.h>
35#include <sys/malloc.h>
36#include <sys/module.h>
37#include <sys/smp.h>
38#include <sys/systm.h>
39
40#include "cpufreq_if.h"
41#include <machine/md_var.h>
42
43#include <contrib/dev/acpica/acpi.h>
44#include <dev/acpica/acpivar.h>
45#include "acpi_if.h"
46
47/* Status/control registers (from the IA-32 System Programming Guide). */
48#define MSR_PERF_STATUS 0x198
49#define MSR_PERF_CTL 0x199
50
51/* Register and bit for enabling SpeedStep. */
52#define MSR_MISC_ENABLE 0x1a0
53#define MSR_SS_ENABLE (1<<16)
54
55/* Frequency and MSR control values. */
56typedef struct {
57 uint16_t freq;
58 uint16_t volts;
59 uint16_t id16;
60 int power;
61} freq_info;
62
63/* Identifying characteristics of a processor and supported frequencies. */
64typedef struct {
65 const char *vendor;
66 uint32_t id32;
67 uint32_t bus_clk;
68 freq_info *freqtab;
69} cpu_info;
70
71struct est_softc {
72 device_t dev;
73 int acpi_settings;
74 freq_info *freq_list;
75};
76
77/* Convert MHz and mV into IDs for passing to the MSR. */
78#define ID16(MHz, mV, bus_clk) \
79 (((MHz / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
80#define ID32(MHz_hi, mV_hi, MHz_lo, mV_lo, bus_clk) \
81 ((ID16(MHz_lo, mV_lo, bus_clk) << 16) | (ID16(MHz_hi, mV_hi, bus_clk)))
82
83/* Format for storing IDs in our table. */
84#define FREQ_INFO(MHz, mV, bus_clk) \
85 { MHz, mV, ID16(MHz, mV, bus_clk), CPUFREQ_VAL_UNKNOWN }
86#define INTEL(tab, zhi, vhi, zlo, vlo, bus_clk) \
87 { GenuineIntel, ID32(zhi, vhi, zlo, vlo, bus_clk), bus_clk, tab }
88
89const char GenuineIntel[] = "GenuineIntel";
90
91/* Default bus clock value for Centrino processors. */
92#define INTEL_BUS_CLK 100
93
94/* XXX Update this if new CPUs have more settings. */
95#define EST_MAX_SETTINGS 10
96CTASSERT(EST_MAX_SETTINGS <= MAX_SETTINGS);
97
98/* Estimate in microseconds of latency for performing a transition. */
99#define EST_TRANS_LAT 10
100
101/*
102 * Frequency (MHz) and voltage (mV) settings. Data from the
103 * Intel Pentium M Processor Datasheet (Order Number 252612), Table 5.
104 *
105 * Dothan processors have multiple VID#s with different settings for
106 * each VID#. Since we can't uniquely identify this info
107 * without undisclosed methods from Intel, we can't support newer
108 * processors with this table method. If ACPI Px states are supported,
109 * we get info from them.
110 */
111static freq_info PM17_130[] = {
112 /* 130nm 1.70GHz Pentium M */
113 FREQ_INFO(1700, 1484, INTEL_BUS_CLK),
114 FREQ_INFO(1400, 1308, INTEL_BUS_CLK),
115 FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
116 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
117 FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
118 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
119 FREQ_INFO( 0, 0, 1),
120};
121static freq_info PM16_130[] = {
122 /* 130nm 1.60GHz Pentium M */
123 FREQ_INFO(1600, 1484, INTEL_BUS_CLK),
124 FREQ_INFO(1400, 1420, INTEL_BUS_CLK),
125 FREQ_INFO(1200, 1276, INTEL_BUS_CLK),
126 FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
127 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
128 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
129 FREQ_INFO( 0, 0, 1),
130};
131static freq_info PM15_130[] = {
132 /* 130nm 1.50GHz Pentium M */
133 FREQ_INFO(1500, 1484, INTEL_BUS_CLK),
134 FREQ_INFO(1400, 1452, INTEL_BUS_CLK),
135 FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
136 FREQ_INFO(1000, 1228, INTEL_BUS_CLK),
137 FREQ_INFO( 800, 1116, INTEL_BUS_CLK),
138 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
139 FREQ_INFO( 0, 0, 1),
140};
141static freq_info PM14_130[] = {
142 /* 130nm 1.40GHz Pentium M */
143 FREQ_INFO(1400, 1484, INTEL_BUS_CLK),
144 FREQ_INFO(1200, 1436, INTEL_BUS_CLK),
145 FREQ_INFO(1000, 1308, INTEL_BUS_CLK),
146 FREQ_INFO( 800, 1180, INTEL_BUS_CLK),
147 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
148 FREQ_INFO( 0, 0, 1),
149};
150static freq_info PM13_130[] = {
151 /* 130nm 1.30GHz Pentium M */
152 FREQ_INFO(1300, 1388, INTEL_BUS_CLK),
153 FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
154 FREQ_INFO(1000, 1292, INTEL_BUS_CLK),
155 FREQ_INFO( 800, 1260, INTEL_BUS_CLK),
156 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
157 FREQ_INFO( 0, 0, 1),
158};
159static freq_info PM13_LV_130[] = {
160 /* 130nm 1.30GHz Low Voltage Pentium M */
161 FREQ_INFO(1300, 1180, INTEL_BUS_CLK),
162 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
163 FREQ_INFO(1100, 1100, INTEL_BUS_CLK),
164 FREQ_INFO(1000, 1020, INTEL_BUS_CLK),
165 FREQ_INFO( 900, 1004, INTEL_BUS_CLK),
166 FREQ_INFO( 800, 988, INTEL_BUS_CLK),
167 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
168 FREQ_INFO( 0, 0, 1),
169};
170static freq_info PM12_LV_130[] = {
171 /* 130 nm 1.20GHz Low Voltage Pentium M */
172 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
173 FREQ_INFO(1100, 1164, INTEL_BUS_CLK),
174 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
175 FREQ_INFO( 900, 1020, INTEL_BUS_CLK),
176 FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
177 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
178 FREQ_INFO( 0, 0, 1),
179};
180static freq_info PM11_LV_130[] = {
181 /* 130 nm 1.10GHz Low Voltage Pentium M */
182 FREQ_INFO(1100, 1180, INTEL_BUS_CLK),
183 FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
184 FREQ_INFO( 900, 1100, INTEL_BUS_CLK),
185 FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
186 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
187 FREQ_INFO( 0, 0, 1),
188};
189static freq_info PM11_ULV_130[] = {
190 /* 130 nm 1.10GHz Ultra Low Voltage Pentium M */
191 FREQ_INFO(1100, 1004, INTEL_BUS_CLK),
192 FREQ_INFO(1000, 988, INTEL_BUS_CLK),
193 FREQ_INFO( 900, 972, INTEL_BUS_CLK),
194 FREQ_INFO( 800, 956, INTEL_BUS_CLK),
195 FREQ_INFO( 600, 844, INTEL_BUS_CLK),
196 FREQ_INFO( 0, 0, 1),
197};
198static freq_info PM10_ULV_130[] = {
199 /* 130 nm 1.00GHz Ultra Low Voltage Pentium M */
200 FREQ_INFO(1000, 1004, INTEL_BUS_CLK),
201 FREQ_INFO( 900, 988, INTEL_BUS_CLK),
202 FREQ_INFO( 800, 972, INTEL_BUS_CLK),
203 FREQ_INFO( 600, 844, INTEL_BUS_CLK),
204 FREQ_INFO( 0, 0, 1),
205};
206
207/*
208 * Data from "Intel Pentium M Processor on 90nm Process with
209 * 2-MB L2 Cache Datasheet", Order Number 302189, Table 5.
210 */
211static freq_info PM_765A_90[] = {
212 /* 90 nm 2.10GHz Pentium M, VID #A */
213 FREQ_INFO(2100, 1340, INTEL_BUS_CLK),
214 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
215 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
216 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
217 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
218 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
219 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
220 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
221 FREQ_INFO( 0, 0, 1),
222};
223static freq_info PM_765B_90[] = {
224 /* 90 nm 2.10GHz Pentium M, VID #B */
225 FREQ_INFO(2100, 1324, INTEL_BUS_CLK),
226 FREQ_INFO(1800, 1260, INTEL_BUS_CLK),
227 FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
228 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
229 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
230 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
231 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
232 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
233 FREQ_INFO( 0, 0, 1),
234};
235static freq_info PM_765C_90[] = {
236 /* 90 nm 2.10GHz Pentium M, VID #C */
237 FREQ_INFO(2100, 1308, INTEL_BUS_CLK),
238 FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
239 FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
240 FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
241 FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
242 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
243 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
244 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
245 FREQ_INFO( 0, 0, 1),
246};
247static freq_info PM_765E_90[] = {
248 /* 90 nm 2.10GHz Pentium M, VID #E */
249 FREQ_INFO(2100, 1356, INTEL_BUS_CLK),
250 FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
251 FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
252 FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
253 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
254 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
255 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
256 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
257 FREQ_INFO( 0, 0, 1),
258};
259static freq_info PM_755A_90[] = {
260 /* 90 nm 2.00GHz Pentium M, VID #A */
261 FREQ_INFO(2000, 1340, INTEL_BUS_CLK),
262 FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
263 FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
264 FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
265 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
266 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
267 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
268 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
269 FREQ_INFO( 0, 0, 1),
270};
271static freq_info PM_755B_90[] = {
272 /* 90 nm 2.00GHz Pentium M, VID #B */
273 FREQ_INFO(2000, 1324, INTEL_BUS_CLK),
274 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
275 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
276 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
277 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
278 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
279 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
280 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
281 FREQ_INFO( 0, 0, 1),
282};
283static freq_info PM_755C_90[] = {
284 /* 90 nm 2.00GHz Pentium M, VID #C */
285 FREQ_INFO(2000, 1308, INTEL_BUS_CLK),
286 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
287 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
288 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
289 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
290 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
291 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
292 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
293 FREQ_INFO( 0, 0, 1),
294};
295static freq_info PM_755D_90[] = {
296 /* 90 nm 2.00GHz Pentium M, VID #D */
297 FREQ_INFO(2000, 1276, INTEL_BUS_CLK),
298 FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
299 FREQ_INFO(1600, 1196, INTEL_BUS_CLK),
300 FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
301 FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
302 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
303 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
304 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
305 FREQ_INFO( 0, 0, 1),
306};
307static freq_info PM_745A_90[] = {
308 /* 90 nm 1.80GHz Pentium M, VID #A */
309 FREQ_INFO(1800, 1340, INTEL_BUS_CLK),
310 FREQ_INFO(1600, 1292, INTEL_BUS_CLK),
311 FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
312 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
313 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
314 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
315 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
316 FREQ_INFO( 0, 0, 1),
317};
318static freq_info PM_745B_90[] = {
319 /* 90 nm 1.80GHz Pentium M, VID #B */
320 FREQ_INFO(1800, 1324, INTEL_BUS_CLK),
321 FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
322 FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
323 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
324 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
325 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
326 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
327 FREQ_INFO( 0, 0, 1),
328};
329static freq_info PM_745C_90[] = {
330 /* 90 nm 1.80GHz Pentium M, VID #C */
331 FREQ_INFO(1800, 1308, INTEL_BUS_CLK),
332 FREQ_INFO(1600, 1260, INTEL_BUS_CLK),
333 FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
334 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
335 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
336 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
337 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
338 FREQ_INFO( 0, 0, 1),
339};
340static freq_info PM_745D_90[] = {
341 /* 90 nm 1.80GHz Pentium M, VID #D */
342 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
343 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
344 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
345 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
346 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
347 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
348 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
349 FREQ_INFO( 0, 0, 1),
350};
351static freq_info PM_735A_90[] = {
352 /* 90 nm 1.70GHz Pentium M, VID #A */
353 FREQ_INFO(1700, 1340, INTEL_BUS_CLK),
354 FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
355 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
356 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
357 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
358 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
359 FREQ_INFO( 0, 0, 1),
360};
361static freq_info PM_735B_90[] = {
362 /* 90 nm 1.70GHz Pentium M, VID #B */
363 FREQ_INFO(1700, 1324, INTEL_BUS_CLK),
364 FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
365 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
366 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
367 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
368 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
369 FREQ_INFO( 0, 0, 1),
370};
371static freq_info PM_735C_90[] = {
372 /* 90 nm 1.70GHz Pentium M, VID #C */
373 FREQ_INFO(1700, 1308, INTEL_BUS_CLK),
374 FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
375 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
376 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
377 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
378 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
379 FREQ_INFO( 0, 0, 1),
380};
381static freq_info PM_735D_90[] = {
382 /* 90 nm 1.70GHz Pentium M, VID #D */
383 FREQ_INFO(1700, 1276, INTEL_BUS_CLK),
384 FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
385 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
386 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
387 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
388 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
389 FREQ_INFO( 0, 0, 1),
390};
391static freq_info PM_725A_90[] = {
392 /* 90 nm 1.60GHz Pentium M, VID #A */
393 FREQ_INFO(1600, 1340, INTEL_BUS_CLK),
394 FREQ_INFO(1400, 1276, INTEL_BUS_CLK),
395 FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
396 FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
397 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
398 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
399 FREQ_INFO( 0, 0, 1),
400};
401static freq_info PM_725B_90[] = {
402 /* 90 nm 1.60GHz Pentium M, VID #B */
403 FREQ_INFO(1600, 1324, INTEL_BUS_CLK),
404 FREQ_INFO(1400, 1260, INTEL_BUS_CLK),
405 FREQ_INFO(1200, 1196, INTEL_BUS_CLK),
406 FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
407 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
408 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
409 FREQ_INFO( 0, 0, 1),
410};
411static freq_info PM_725C_90[] = {
412 /* 90 nm 1.60GHz Pentium M, VID #C */
413 FREQ_INFO(1600, 1308, INTEL_BUS_CLK),
414 FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
415 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
416 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
417 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
418 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
419 FREQ_INFO( 0, 0, 1),
420};
421static freq_info PM_725D_90[] = {
422 /* 90 nm 1.60GHz Pentium M, VID #D */
423 FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
424 FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
425 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
426 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
427 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
428 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
429 FREQ_INFO( 0, 0, 1),
430};
431static freq_info PM_715A_90[] = {
432 /* 90 nm 1.50GHz Pentium M, VID #A */
433 FREQ_INFO(1500, 1340, INTEL_BUS_CLK),
434 FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
435 FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
436 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
437 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
438 FREQ_INFO( 0, 0, 1),
439};
440static freq_info PM_715B_90[] = {
441 /* 90 nm 1.50GHz Pentium M, VID #B */
442 FREQ_INFO(1500, 1324, INTEL_BUS_CLK),
443 FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
444 FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
445 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
446 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
447 FREQ_INFO( 0, 0, 1),
448};
449static freq_info PM_715C_90[] = {
450 /* 90 nm 1.50GHz Pentium M, VID #C */
451 FREQ_INFO(1500, 1308, INTEL_BUS_CLK),
452 FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
453 FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
454 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
455 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
456 FREQ_INFO( 0, 0, 1),
457};
458static freq_info PM_715D_90[] = {
459 /* 90 nm 1.50GHz Pentium M, VID #D */
460 FREQ_INFO(1500, 1276, INTEL_BUS_CLK),
461 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
462 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
463 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
464 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
465 FREQ_INFO( 0, 0, 1),
466};
30
31#include <sys/param.h>
32#include <sys/bus.h>
33#include <sys/cpu.h>
34#include <sys/kernel.h>
35#include <sys/malloc.h>
36#include <sys/module.h>
37#include <sys/smp.h>
38#include <sys/systm.h>
39
40#include "cpufreq_if.h"
41#include <machine/md_var.h>
42
43#include <contrib/dev/acpica/acpi.h>
44#include <dev/acpica/acpivar.h>
45#include "acpi_if.h"
46
47/* Status/control registers (from the IA-32 System Programming Guide). */
48#define MSR_PERF_STATUS 0x198
49#define MSR_PERF_CTL 0x199
50
51/* Register and bit for enabling SpeedStep. */
52#define MSR_MISC_ENABLE 0x1a0
53#define MSR_SS_ENABLE (1<<16)
54
55/* Frequency and MSR control values. */
56typedef struct {
57 uint16_t freq;
58 uint16_t volts;
59 uint16_t id16;
60 int power;
61} freq_info;
62
63/* Identifying characteristics of a processor and supported frequencies. */
64typedef struct {
65 const char *vendor;
66 uint32_t id32;
67 uint32_t bus_clk;
68 freq_info *freqtab;
69} cpu_info;
70
71struct est_softc {
72 device_t dev;
73 int acpi_settings;
74 freq_info *freq_list;
75};
76
77/* Convert MHz and mV into IDs for passing to the MSR. */
78#define ID16(MHz, mV, bus_clk) \
79 (((MHz / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
80#define ID32(MHz_hi, mV_hi, MHz_lo, mV_lo, bus_clk) \
81 ((ID16(MHz_lo, mV_lo, bus_clk) << 16) | (ID16(MHz_hi, mV_hi, bus_clk)))
82
83/* Format for storing IDs in our table. */
84#define FREQ_INFO(MHz, mV, bus_clk) \
85 { MHz, mV, ID16(MHz, mV, bus_clk), CPUFREQ_VAL_UNKNOWN }
86#define INTEL(tab, zhi, vhi, zlo, vlo, bus_clk) \
87 { GenuineIntel, ID32(zhi, vhi, zlo, vlo, bus_clk), bus_clk, tab }
88
89const char GenuineIntel[] = "GenuineIntel";
90
91/* Default bus clock value for Centrino processors. */
92#define INTEL_BUS_CLK 100
93
94/* XXX Update this if new CPUs have more settings. */
95#define EST_MAX_SETTINGS 10
96CTASSERT(EST_MAX_SETTINGS <= MAX_SETTINGS);
97
98/* Estimate in microseconds of latency for performing a transition. */
99#define EST_TRANS_LAT 10
100
101/*
102 * Frequency (MHz) and voltage (mV) settings. Data from the
103 * Intel Pentium M Processor Datasheet (Order Number 252612), Table 5.
104 *
105 * Dothan processors have multiple VID#s with different settings for
106 * each VID#. Since we can't uniquely identify this info
107 * without undisclosed methods from Intel, we can't support newer
108 * processors with this table method. If ACPI Px states are supported,
109 * we get info from them.
110 */
111static freq_info PM17_130[] = {
112 /* 130nm 1.70GHz Pentium M */
113 FREQ_INFO(1700, 1484, INTEL_BUS_CLK),
114 FREQ_INFO(1400, 1308, INTEL_BUS_CLK),
115 FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
116 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
117 FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
118 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
119 FREQ_INFO( 0, 0, 1),
120};
121static freq_info PM16_130[] = {
122 /* 130nm 1.60GHz Pentium M */
123 FREQ_INFO(1600, 1484, INTEL_BUS_CLK),
124 FREQ_INFO(1400, 1420, INTEL_BUS_CLK),
125 FREQ_INFO(1200, 1276, INTEL_BUS_CLK),
126 FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
127 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
128 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
129 FREQ_INFO( 0, 0, 1),
130};
131static freq_info PM15_130[] = {
132 /* 130nm 1.50GHz Pentium M */
133 FREQ_INFO(1500, 1484, INTEL_BUS_CLK),
134 FREQ_INFO(1400, 1452, INTEL_BUS_CLK),
135 FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
136 FREQ_INFO(1000, 1228, INTEL_BUS_CLK),
137 FREQ_INFO( 800, 1116, INTEL_BUS_CLK),
138 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
139 FREQ_INFO( 0, 0, 1),
140};
141static freq_info PM14_130[] = {
142 /* 130nm 1.40GHz Pentium M */
143 FREQ_INFO(1400, 1484, INTEL_BUS_CLK),
144 FREQ_INFO(1200, 1436, INTEL_BUS_CLK),
145 FREQ_INFO(1000, 1308, INTEL_BUS_CLK),
146 FREQ_INFO( 800, 1180, INTEL_BUS_CLK),
147 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
148 FREQ_INFO( 0, 0, 1),
149};
150static freq_info PM13_130[] = {
151 /* 130nm 1.30GHz Pentium M */
152 FREQ_INFO(1300, 1388, INTEL_BUS_CLK),
153 FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
154 FREQ_INFO(1000, 1292, INTEL_BUS_CLK),
155 FREQ_INFO( 800, 1260, INTEL_BUS_CLK),
156 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
157 FREQ_INFO( 0, 0, 1),
158};
159static freq_info PM13_LV_130[] = {
160 /* 130nm 1.30GHz Low Voltage Pentium M */
161 FREQ_INFO(1300, 1180, INTEL_BUS_CLK),
162 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
163 FREQ_INFO(1100, 1100, INTEL_BUS_CLK),
164 FREQ_INFO(1000, 1020, INTEL_BUS_CLK),
165 FREQ_INFO( 900, 1004, INTEL_BUS_CLK),
166 FREQ_INFO( 800, 988, INTEL_BUS_CLK),
167 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
168 FREQ_INFO( 0, 0, 1),
169};
170static freq_info PM12_LV_130[] = {
171 /* 130 nm 1.20GHz Low Voltage Pentium M */
172 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
173 FREQ_INFO(1100, 1164, INTEL_BUS_CLK),
174 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
175 FREQ_INFO( 900, 1020, INTEL_BUS_CLK),
176 FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
177 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
178 FREQ_INFO( 0, 0, 1),
179};
180static freq_info PM11_LV_130[] = {
181 /* 130 nm 1.10GHz Low Voltage Pentium M */
182 FREQ_INFO(1100, 1180, INTEL_BUS_CLK),
183 FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
184 FREQ_INFO( 900, 1100, INTEL_BUS_CLK),
185 FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
186 FREQ_INFO( 600, 956, INTEL_BUS_CLK),
187 FREQ_INFO( 0, 0, 1),
188};
189static freq_info PM11_ULV_130[] = {
190 /* 130 nm 1.10GHz Ultra Low Voltage Pentium M */
191 FREQ_INFO(1100, 1004, INTEL_BUS_CLK),
192 FREQ_INFO(1000, 988, INTEL_BUS_CLK),
193 FREQ_INFO( 900, 972, INTEL_BUS_CLK),
194 FREQ_INFO( 800, 956, INTEL_BUS_CLK),
195 FREQ_INFO( 600, 844, INTEL_BUS_CLK),
196 FREQ_INFO( 0, 0, 1),
197};
198static freq_info PM10_ULV_130[] = {
199 /* 130 nm 1.00GHz Ultra Low Voltage Pentium M */
200 FREQ_INFO(1000, 1004, INTEL_BUS_CLK),
201 FREQ_INFO( 900, 988, INTEL_BUS_CLK),
202 FREQ_INFO( 800, 972, INTEL_BUS_CLK),
203 FREQ_INFO( 600, 844, INTEL_BUS_CLK),
204 FREQ_INFO( 0, 0, 1),
205};
206
207/*
208 * Data from "Intel Pentium M Processor on 90nm Process with
209 * 2-MB L2 Cache Datasheet", Order Number 302189, Table 5.
210 */
211static freq_info PM_765A_90[] = {
212 /* 90 nm 2.10GHz Pentium M, VID #A */
213 FREQ_INFO(2100, 1340, INTEL_BUS_CLK),
214 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
215 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
216 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
217 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
218 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
219 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
220 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
221 FREQ_INFO( 0, 0, 1),
222};
223static freq_info PM_765B_90[] = {
224 /* 90 nm 2.10GHz Pentium M, VID #B */
225 FREQ_INFO(2100, 1324, INTEL_BUS_CLK),
226 FREQ_INFO(1800, 1260, INTEL_BUS_CLK),
227 FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
228 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
229 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
230 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
231 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
232 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
233 FREQ_INFO( 0, 0, 1),
234};
235static freq_info PM_765C_90[] = {
236 /* 90 nm 2.10GHz Pentium M, VID #C */
237 FREQ_INFO(2100, 1308, INTEL_BUS_CLK),
238 FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
239 FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
240 FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
241 FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
242 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
243 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
244 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
245 FREQ_INFO( 0, 0, 1),
246};
247static freq_info PM_765E_90[] = {
248 /* 90 nm 2.10GHz Pentium M, VID #E */
249 FREQ_INFO(2100, 1356, INTEL_BUS_CLK),
250 FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
251 FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
252 FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
253 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
254 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
255 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
256 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
257 FREQ_INFO( 0, 0, 1),
258};
259static freq_info PM_755A_90[] = {
260 /* 90 nm 2.00GHz Pentium M, VID #A */
261 FREQ_INFO(2000, 1340, INTEL_BUS_CLK),
262 FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
263 FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
264 FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
265 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
266 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
267 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
268 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
269 FREQ_INFO( 0, 0, 1),
270};
271static freq_info PM_755B_90[] = {
272 /* 90 nm 2.00GHz Pentium M, VID #B */
273 FREQ_INFO(2000, 1324, INTEL_BUS_CLK),
274 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
275 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
276 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
277 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
278 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
279 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
280 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
281 FREQ_INFO( 0, 0, 1),
282};
283static freq_info PM_755C_90[] = {
284 /* 90 nm 2.00GHz Pentium M, VID #C */
285 FREQ_INFO(2000, 1308, INTEL_BUS_CLK),
286 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
287 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
288 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
289 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
290 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
291 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
292 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
293 FREQ_INFO( 0, 0, 1),
294};
295static freq_info PM_755D_90[] = {
296 /* 90 nm 2.00GHz Pentium M, VID #D */
297 FREQ_INFO(2000, 1276, INTEL_BUS_CLK),
298 FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
299 FREQ_INFO(1600, 1196, INTEL_BUS_CLK),
300 FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
301 FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
302 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
303 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
304 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
305 FREQ_INFO( 0, 0, 1),
306};
307static freq_info PM_745A_90[] = {
308 /* 90 nm 1.80GHz Pentium M, VID #A */
309 FREQ_INFO(1800, 1340, INTEL_BUS_CLK),
310 FREQ_INFO(1600, 1292, INTEL_BUS_CLK),
311 FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
312 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
313 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
314 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
315 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
316 FREQ_INFO( 0, 0, 1),
317};
318static freq_info PM_745B_90[] = {
319 /* 90 nm 1.80GHz Pentium M, VID #B */
320 FREQ_INFO(1800, 1324, INTEL_BUS_CLK),
321 FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
322 FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
323 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
324 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
325 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
326 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
327 FREQ_INFO( 0, 0, 1),
328};
329static freq_info PM_745C_90[] = {
330 /* 90 nm 1.80GHz Pentium M, VID #C */
331 FREQ_INFO(1800, 1308, INTEL_BUS_CLK),
332 FREQ_INFO(1600, 1260, INTEL_BUS_CLK),
333 FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
334 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
335 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
336 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
337 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
338 FREQ_INFO( 0, 0, 1),
339};
340static freq_info PM_745D_90[] = {
341 /* 90 nm 1.80GHz Pentium M, VID #D */
342 FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
343 FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
344 FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
345 FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
346 FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
347 FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
348 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
349 FREQ_INFO( 0, 0, 1),
350};
351static freq_info PM_735A_90[] = {
352 /* 90 nm 1.70GHz Pentium M, VID #A */
353 FREQ_INFO(1700, 1340, INTEL_BUS_CLK),
354 FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
355 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
356 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
357 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
358 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
359 FREQ_INFO( 0, 0, 1),
360};
361static freq_info PM_735B_90[] = {
362 /* 90 nm 1.70GHz Pentium M, VID #B */
363 FREQ_INFO(1700, 1324, INTEL_BUS_CLK),
364 FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
365 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
366 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
367 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
368 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
369 FREQ_INFO( 0, 0, 1),
370};
371static freq_info PM_735C_90[] = {
372 /* 90 nm 1.70GHz Pentium M, VID #C */
373 FREQ_INFO(1700, 1308, INTEL_BUS_CLK),
374 FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
375 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
376 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
377 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
378 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
379 FREQ_INFO( 0, 0, 1),
380};
381static freq_info PM_735D_90[] = {
382 /* 90 nm 1.70GHz Pentium M, VID #D */
383 FREQ_INFO(1700, 1276, INTEL_BUS_CLK),
384 FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
385 FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
386 FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
387 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
388 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
389 FREQ_INFO( 0, 0, 1),
390};
391static freq_info PM_725A_90[] = {
392 /* 90 nm 1.60GHz Pentium M, VID #A */
393 FREQ_INFO(1600, 1340, INTEL_BUS_CLK),
394 FREQ_INFO(1400, 1276, INTEL_BUS_CLK),
395 FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
396 FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
397 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
398 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
399 FREQ_INFO( 0, 0, 1),
400};
401static freq_info PM_725B_90[] = {
402 /* 90 nm 1.60GHz Pentium M, VID #B */
403 FREQ_INFO(1600, 1324, INTEL_BUS_CLK),
404 FREQ_INFO(1400, 1260, INTEL_BUS_CLK),
405 FREQ_INFO(1200, 1196, INTEL_BUS_CLK),
406 FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
407 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
408 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
409 FREQ_INFO( 0, 0, 1),
410};
411static freq_info PM_725C_90[] = {
412 /* 90 nm 1.60GHz Pentium M, VID #C */
413 FREQ_INFO(1600, 1308, INTEL_BUS_CLK),
414 FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
415 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
416 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
417 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
418 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
419 FREQ_INFO( 0, 0, 1),
420};
421static freq_info PM_725D_90[] = {
422 /* 90 nm 1.60GHz Pentium M, VID #D */
423 FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
424 FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
425 FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
426 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
427 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
428 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
429 FREQ_INFO( 0, 0, 1),
430};
431static freq_info PM_715A_90[] = {
432 /* 90 nm 1.50GHz Pentium M, VID #A */
433 FREQ_INFO(1500, 1340, INTEL_BUS_CLK),
434 FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
435 FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
436 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
437 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
438 FREQ_INFO( 0, 0, 1),
439};
440static freq_info PM_715B_90[] = {
441 /* 90 nm 1.50GHz Pentium M, VID #B */
442 FREQ_INFO(1500, 1324, INTEL_BUS_CLK),
443 FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
444 FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
445 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
446 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
447 FREQ_INFO( 0, 0, 1),
448};
449static freq_info PM_715C_90[] = {
450 /* 90 nm 1.50GHz Pentium M, VID #C */
451 FREQ_INFO(1500, 1308, INTEL_BUS_CLK),
452 FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
453 FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
454 FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
455 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
456 FREQ_INFO( 0, 0, 1),
457};
458static freq_info PM_715D_90[] = {
459 /* 90 nm 1.50GHz Pentium M, VID #D */
460 FREQ_INFO(1500, 1276, INTEL_BUS_CLK),
461 FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
462 FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
463 FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
464 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
465 FREQ_INFO( 0, 0, 1),
466};
467static freq_info PM_778_90[] = {
468 /* 90 nm 1.60GHz Low Voltage Pentium M */
469 FREQ_INFO(1600, 1116, INTEL_BUS_CLK),
470 FREQ_INFO(1500, 1116, INTEL_BUS_CLK),
471 FREQ_INFO(1400, 1100, INTEL_BUS_CLK),
472 FREQ_INFO(1300, 1084, INTEL_BUS_CLK),
473 FREQ_INFO(1200, 1068, INTEL_BUS_CLK),
474 FREQ_INFO(1100, 1052, INTEL_BUS_CLK),
475 FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
476 FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
477 FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
478 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
479 FREQ_INFO( 0, 0, 1),
480};
481static freq_info PM_758_90[] = {
482 /* 90 nm 1.50GHz Low Voltage Pentium M */
483 FREQ_INFO(1500, 1116, INTEL_BUS_CLK),
484 FREQ_INFO(1400, 1116, INTEL_BUS_CLK),
485 FREQ_INFO(1300, 1100, INTEL_BUS_CLK),
486 FREQ_INFO(1200, 1084, INTEL_BUS_CLK),
487 FREQ_INFO(1100, 1068, INTEL_BUS_CLK),
488 FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
489 FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
490 FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
491 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
492 FREQ_INFO( 0, 0, 1),
493};
467static freq_info PM_738_90[] = {
468 /* 90 nm 1.40GHz Low Voltage Pentium M */
469 FREQ_INFO(1400, 1116, INTEL_BUS_CLK),
470 FREQ_INFO(1300, 1116, INTEL_BUS_CLK),
471 FREQ_INFO(1200, 1100, INTEL_BUS_CLK),
472 FREQ_INFO(1100, 1068, INTEL_BUS_CLK),
473 FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
474 FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
475 FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
476 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
477 FREQ_INFO( 0, 0, 1),
478};
494static freq_info PM_738_90[] = {
495 /* 90 nm 1.40GHz Low Voltage Pentium M */
496 FREQ_INFO(1400, 1116, INTEL_BUS_CLK),
497 FREQ_INFO(1300, 1116, INTEL_BUS_CLK),
498 FREQ_INFO(1200, 1100, INTEL_BUS_CLK),
499 FREQ_INFO(1100, 1068, INTEL_BUS_CLK),
500 FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
501 FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
502 FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
503 FREQ_INFO( 600, 988, INTEL_BUS_CLK),
504 FREQ_INFO( 0, 0, 1),
505};
506static freq_info PM_773G_90[] = {
507 /* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #G */
508 FREQ_INFO(1300, 956, INTEL_BUS_CLK),
509 FREQ_INFO(1200, 940, INTEL_BUS_CLK),
510 FREQ_INFO(1100, 924, INTEL_BUS_CLK),
511 FREQ_INFO(1000, 908, INTEL_BUS_CLK),
512 FREQ_INFO( 900, 876, INTEL_BUS_CLK),
513 FREQ_INFO( 800, 860, INTEL_BUS_CLK),
514 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
515};
516static freq_info PM_773H_90[] = {
517 /* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #H */
518 FREQ_INFO(1300, 940, INTEL_BUS_CLK),
519 FREQ_INFO(1200, 924, INTEL_BUS_CLK),
520 FREQ_INFO(1100, 908, INTEL_BUS_CLK),
521 FREQ_INFO(1000, 892, INTEL_BUS_CLK),
522 FREQ_INFO( 900, 876, INTEL_BUS_CLK),
523 FREQ_INFO( 800, 860, INTEL_BUS_CLK),
524 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
525};
526static freq_info PM_773I_90[] = {
527 /* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #I */
528 FREQ_INFO(1300, 924, INTEL_BUS_CLK),
529 FREQ_INFO(1200, 908, INTEL_BUS_CLK),
530 FREQ_INFO(1100, 892, INTEL_BUS_CLK),
531 FREQ_INFO(1000, 876, INTEL_BUS_CLK),
532 FREQ_INFO( 900, 860, INTEL_BUS_CLK),
533 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
534 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
535};
536static freq_info PM_773J_90[] = {
537 /* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #J */
538 FREQ_INFO(1300, 908, INTEL_BUS_CLK),
539 FREQ_INFO(1200, 908, INTEL_BUS_CLK),
540 FREQ_INFO(1100, 892, INTEL_BUS_CLK),
541 FREQ_INFO(1000, 876, INTEL_BUS_CLK),
542 FREQ_INFO( 900, 860, INTEL_BUS_CLK),
543 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
544 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
545};
546static freq_info PM_773K_90[] = {
547 /* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #K */
548 FREQ_INFO(1300, 892, INTEL_BUS_CLK),
549 FREQ_INFO(1200, 892, INTEL_BUS_CLK),
550 FREQ_INFO(1100, 876, INTEL_BUS_CLK),
551 FREQ_INFO(1000, 860, INTEL_BUS_CLK),
552 FREQ_INFO( 900, 860, INTEL_BUS_CLK),
553 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
554 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
555};
556static freq_info PM_773L_90[] = {
557 /* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #L */
558 FREQ_INFO(1300, 876, INTEL_BUS_CLK),
559 FREQ_INFO(1200, 876, INTEL_BUS_CLK),
560 FREQ_INFO(1100, 860, INTEL_BUS_CLK),
561 FREQ_INFO(1000, 860, INTEL_BUS_CLK),
562 FREQ_INFO( 900, 844, INTEL_BUS_CLK),
563 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
564 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
565};
566static freq_info PM_753G_90[] = {
567 /* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #G */
568 FREQ_INFO(1200, 956, INTEL_BUS_CLK),
569 FREQ_INFO(1100, 940, INTEL_BUS_CLK),
570 FREQ_INFO(1000, 908, INTEL_BUS_CLK),
571 FREQ_INFO( 900, 892, INTEL_BUS_CLK),
572 FREQ_INFO( 800, 860, INTEL_BUS_CLK),
573 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
574};
575static freq_info PM_753H_90[] = {
576 /* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #H */
577 FREQ_INFO(1200, 940, INTEL_BUS_CLK),
578 FREQ_INFO(1100, 924, INTEL_BUS_CLK),
579 FREQ_INFO(1000, 908, INTEL_BUS_CLK),
580 FREQ_INFO( 900, 876, INTEL_BUS_CLK),
581 FREQ_INFO( 800, 860, INTEL_BUS_CLK),
582 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
583};
584static freq_info PM_753I_90[] = {
585 /* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #I */
586 FREQ_INFO(1200, 924, INTEL_BUS_CLK),
587 FREQ_INFO(1100, 908, INTEL_BUS_CLK),
588 FREQ_INFO(1000, 892, INTEL_BUS_CLK),
589 FREQ_INFO( 900, 876, INTEL_BUS_CLK),
590 FREQ_INFO( 800, 860, INTEL_BUS_CLK),
591 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
592};
593static freq_info PM_753J_90[] = {
594 /* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #J */
595 FREQ_INFO(1200, 908, INTEL_BUS_CLK),
596 FREQ_INFO(1100, 892, INTEL_BUS_CLK),
597 FREQ_INFO(1000, 876, INTEL_BUS_CLK),
598 FREQ_INFO( 900, 860, INTEL_BUS_CLK),
599 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
600 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
601};
602static freq_info PM_753K_90[] = {
603 /* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #K */
604 FREQ_INFO(1200, 892, INTEL_BUS_CLK),
605 FREQ_INFO(1100, 892, INTEL_BUS_CLK),
606 FREQ_INFO(1000, 876, INTEL_BUS_CLK),
607 FREQ_INFO( 900, 860, INTEL_BUS_CLK),
608 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
609 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
610};
611static freq_info PM_753L_90[] = {
612 /* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #L */
613 FREQ_INFO(1200, 876, INTEL_BUS_CLK),
614 FREQ_INFO(1100, 876, INTEL_BUS_CLK),
615 FREQ_INFO(1000, 860, INTEL_BUS_CLK),
616 FREQ_INFO( 900, 844, INTEL_BUS_CLK),
617 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
618 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
619};
620
621static freq_info PM_733JG_90[] = {
622 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #G */
623 FREQ_INFO(1100, 956, INTEL_BUS_CLK),
624 FREQ_INFO(1000, 940, INTEL_BUS_CLK),
625 FREQ_INFO( 900, 908, INTEL_BUS_CLK),
626 FREQ_INFO( 800, 876, INTEL_BUS_CLK),
627 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
628};
629static freq_info PM_733JH_90[] = {
630 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #H */
631 FREQ_INFO(1100, 940, INTEL_BUS_CLK),
632 FREQ_INFO(1000, 924, INTEL_BUS_CLK),
633 FREQ_INFO( 900, 892, INTEL_BUS_CLK),
634 FREQ_INFO( 800, 876, INTEL_BUS_CLK),
635 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
636};
637static freq_info PM_733JI_90[] = {
638 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #I */
639 FREQ_INFO(1100, 924, INTEL_BUS_CLK),
640 FREQ_INFO(1000, 908, INTEL_BUS_CLK),
641 FREQ_INFO( 900, 892, INTEL_BUS_CLK),
642 FREQ_INFO( 800, 860, INTEL_BUS_CLK),
643 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
644};
645static freq_info PM_733JJ_90[] = {
646 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #J */
647 FREQ_INFO(1100, 908, INTEL_BUS_CLK),
648 FREQ_INFO(1000, 892, INTEL_BUS_CLK),
649 FREQ_INFO( 900, 876, INTEL_BUS_CLK),
650 FREQ_INFO( 800, 860, INTEL_BUS_CLK),
651 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
652};
653static freq_info PM_733JK_90[] = {
654 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #K */
655 FREQ_INFO(1100, 892, INTEL_BUS_CLK),
656 FREQ_INFO(1000, 876, INTEL_BUS_CLK),
657 FREQ_INFO( 900, 860, INTEL_BUS_CLK),
658 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
659 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
660};
661static freq_info PM_733JL_90[] = {
662 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #L */
663 FREQ_INFO(1100, 876, INTEL_BUS_CLK),
664 FREQ_INFO(1000, 876, INTEL_BUS_CLK),
665 FREQ_INFO( 900, 860, INTEL_BUS_CLK),
666 FREQ_INFO( 800, 844, INTEL_BUS_CLK),
667 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
668};
479static freq_info PM_733_90[] = {
480 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M */
481 FREQ_INFO(1100, 940, INTEL_BUS_CLK),
482 FREQ_INFO(1000, 924, INTEL_BUS_CLK),
483 FREQ_INFO( 900, 892, INTEL_BUS_CLK),
484 FREQ_INFO( 800, 876, INTEL_BUS_CLK),
485 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
486 FREQ_INFO( 0, 0, 1),
487};
488static freq_info PM_723_90[] = {
489 /* 90 nm 1.00GHz Ultra Low Voltage Pentium M */
490 FREQ_INFO(1000, 940, INTEL_BUS_CLK),
491 FREQ_INFO( 900, 908, INTEL_BUS_CLK),
492 FREQ_INFO( 800, 876, INTEL_BUS_CLK),
493 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
494 FREQ_INFO( 0, 0, 1),
495};
496
497static cpu_info ESTprocs[] = {
498 INTEL(PM17_130, 1700, 1484, 600, 956, INTEL_BUS_CLK),
499 INTEL(PM16_130, 1600, 1484, 600, 956, INTEL_BUS_CLK),
500 INTEL(PM15_130, 1500, 1484, 600, 956, INTEL_BUS_CLK),
501 INTEL(PM14_130, 1400, 1484, 600, 956, INTEL_BUS_CLK),
502 INTEL(PM13_130, 1300, 1388, 600, 956, INTEL_BUS_CLK),
503 INTEL(PM13_LV_130, 1300, 1180, 600, 956, INTEL_BUS_CLK),
504 INTEL(PM12_LV_130, 1200, 1180, 600, 956, INTEL_BUS_CLK),
505 INTEL(PM11_LV_130, 1100, 1180, 600, 956, INTEL_BUS_CLK),
506 INTEL(PM11_ULV_130, 1100, 1004, 600, 844, INTEL_BUS_CLK),
507 INTEL(PM10_ULV_130, 1000, 1004, 600, 844, INTEL_BUS_CLK),
508 INTEL(PM_765A_90, 2100, 1340, 600, 988, INTEL_BUS_CLK),
509 INTEL(PM_765B_90, 2100, 1324, 600, 988, INTEL_BUS_CLK),
510 INTEL(PM_765C_90, 2100, 1308, 600, 988, INTEL_BUS_CLK),
511 INTEL(PM_765E_90, 2100, 1356, 600, 988, INTEL_BUS_CLK),
512 INTEL(PM_755A_90, 2000, 1340, 600, 988, INTEL_BUS_CLK),
513 INTEL(PM_755B_90, 2000, 1324, 600, 988, INTEL_BUS_CLK),
514 INTEL(PM_755C_90, 2000, 1308, 600, 988, INTEL_BUS_CLK),
515 INTEL(PM_755D_90, 2000, 1276, 600, 988, INTEL_BUS_CLK),
516 INTEL(PM_745A_90, 1800, 1340, 600, 988, INTEL_BUS_CLK),
517 INTEL(PM_745B_90, 1800, 1324, 600, 988, INTEL_BUS_CLK),
518 INTEL(PM_745C_90, 1800, 1308, 600, 988, INTEL_BUS_CLK),
519 INTEL(PM_745D_90, 1800, 1276, 600, 988, INTEL_BUS_CLK),
520 INTEL(PM_735A_90, 1700, 1340, 600, 988, INTEL_BUS_CLK),
521 INTEL(PM_735B_90, 1700, 1324, 600, 988, INTEL_BUS_CLK),
522 INTEL(PM_735C_90, 1700, 1308, 600, 988, INTEL_BUS_CLK),
523 INTEL(PM_735D_90, 1700, 1276, 600, 988, INTEL_BUS_CLK),
524 INTEL(PM_725A_90, 1600, 1340, 600, 988, INTEL_BUS_CLK),
525 INTEL(PM_725B_90, 1600, 1324, 600, 988, INTEL_BUS_CLK),
526 INTEL(PM_725C_90, 1600, 1308, 600, 988, INTEL_BUS_CLK),
527 INTEL(PM_725D_90, 1600, 1276, 600, 988, INTEL_BUS_CLK),
528 INTEL(PM_715A_90, 1500, 1340, 600, 988, INTEL_BUS_CLK),
529 INTEL(PM_715B_90, 1500, 1324, 600, 988, INTEL_BUS_CLK),
530 INTEL(PM_715C_90, 1500, 1308, 600, 988, INTEL_BUS_CLK),
531 INTEL(PM_715D_90, 1500, 1276, 600, 988, INTEL_BUS_CLK),
669static freq_info PM_733_90[] = {
670 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M */
671 FREQ_INFO(1100, 940, INTEL_BUS_CLK),
672 FREQ_INFO(1000, 924, INTEL_BUS_CLK),
673 FREQ_INFO( 900, 892, INTEL_BUS_CLK),
674 FREQ_INFO( 800, 876, INTEL_BUS_CLK),
675 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
676 FREQ_INFO( 0, 0, 1),
677};
678static freq_info PM_723_90[] = {
679 /* 90 nm 1.00GHz Ultra Low Voltage Pentium M */
680 FREQ_INFO(1000, 940, INTEL_BUS_CLK),
681 FREQ_INFO( 900, 908, INTEL_BUS_CLK),
682 FREQ_INFO( 800, 876, INTEL_BUS_CLK),
683 FREQ_INFO( 600, 812, INTEL_BUS_CLK),
684 FREQ_INFO( 0, 0, 1),
685};
686
687static cpu_info ESTprocs[] = {
688 INTEL(PM17_130, 1700, 1484, 600, 956, INTEL_BUS_CLK),
689 INTEL(PM16_130, 1600, 1484, 600, 956, INTEL_BUS_CLK),
690 INTEL(PM15_130, 1500, 1484, 600, 956, INTEL_BUS_CLK),
691 INTEL(PM14_130, 1400, 1484, 600, 956, INTEL_BUS_CLK),
692 INTEL(PM13_130, 1300, 1388, 600, 956, INTEL_BUS_CLK),
693 INTEL(PM13_LV_130, 1300, 1180, 600, 956, INTEL_BUS_CLK),
694 INTEL(PM12_LV_130, 1200, 1180, 600, 956, INTEL_BUS_CLK),
695 INTEL(PM11_LV_130, 1100, 1180, 600, 956, INTEL_BUS_CLK),
696 INTEL(PM11_ULV_130, 1100, 1004, 600, 844, INTEL_BUS_CLK),
697 INTEL(PM10_ULV_130, 1000, 1004, 600, 844, INTEL_BUS_CLK),
698 INTEL(PM_765A_90, 2100, 1340, 600, 988, INTEL_BUS_CLK),
699 INTEL(PM_765B_90, 2100, 1324, 600, 988, INTEL_BUS_CLK),
700 INTEL(PM_765C_90, 2100, 1308, 600, 988, INTEL_BUS_CLK),
701 INTEL(PM_765E_90, 2100, 1356, 600, 988, INTEL_BUS_CLK),
702 INTEL(PM_755A_90, 2000, 1340, 600, 988, INTEL_BUS_CLK),
703 INTEL(PM_755B_90, 2000, 1324, 600, 988, INTEL_BUS_CLK),
704 INTEL(PM_755C_90, 2000, 1308, 600, 988, INTEL_BUS_CLK),
705 INTEL(PM_755D_90, 2000, 1276, 600, 988, INTEL_BUS_CLK),
706 INTEL(PM_745A_90, 1800, 1340, 600, 988, INTEL_BUS_CLK),
707 INTEL(PM_745B_90, 1800, 1324, 600, 988, INTEL_BUS_CLK),
708 INTEL(PM_745C_90, 1800, 1308, 600, 988, INTEL_BUS_CLK),
709 INTEL(PM_745D_90, 1800, 1276, 600, 988, INTEL_BUS_CLK),
710 INTEL(PM_735A_90, 1700, 1340, 600, 988, INTEL_BUS_CLK),
711 INTEL(PM_735B_90, 1700, 1324, 600, 988, INTEL_BUS_CLK),
712 INTEL(PM_735C_90, 1700, 1308, 600, 988, INTEL_BUS_CLK),
713 INTEL(PM_735D_90, 1700, 1276, 600, 988, INTEL_BUS_CLK),
714 INTEL(PM_725A_90, 1600, 1340, 600, 988, INTEL_BUS_CLK),
715 INTEL(PM_725B_90, 1600, 1324, 600, 988, INTEL_BUS_CLK),
716 INTEL(PM_725C_90, 1600, 1308, 600, 988, INTEL_BUS_CLK),
717 INTEL(PM_725D_90, 1600, 1276, 600, 988, INTEL_BUS_CLK),
718 INTEL(PM_715A_90, 1500, 1340, 600, 988, INTEL_BUS_CLK),
719 INTEL(PM_715B_90, 1500, 1324, 600, 988, INTEL_BUS_CLK),
720 INTEL(PM_715C_90, 1500, 1308, 600, 988, INTEL_BUS_CLK),
721 INTEL(PM_715D_90, 1500, 1276, 600, 988, INTEL_BUS_CLK),
722 INTEL(PM_778_90, 1600, 1116, 600, 988, INTEL_BUS_CLK),
723 INTEL(PM_758_90, 1500, 1116, 600, 988, INTEL_BUS_CLK),
532 INTEL(PM_738_90, 1400, 1116, 600, 988, INTEL_BUS_CLK),
724 INTEL(PM_738_90, 1400, 1116, 600, 988, INTEL_BUS_CLK),
725 INTEL(PM_773G_90, 1300, 956, 600, 812, INTEL_BUS_CLK),
726 INTEL(PM_773H_90, 1300, 940, 600, 812, INTEL_BUS_CLK),
727 INTEL(PM_773I_90, 1300, 924, 600, 812, INTEL_BUS_CLK),
728 INTEL(PM_773J_90, 1300, 908, 600, 812, INTEL_BUS_CLK),
729 INTEL(PM_773K_90, 1300, 892, 600, 812, INTEL_BUS_CLK),
730 INTEL(PM_773L_90, 1300, 876, 600, 812, INTEL_BUS_CLK),
731 INTEL(PM_753G_90, 1200, 956, 600, 812, INTEL_BUS_CLK),
732 INTEL(PM_753H_90, 1200, 940, 600, 812, INTEL_BUS_CLK),
733 INTEL(PM_753I_90, 1200, 924, 600, 812, INTEL_BUS_CLK),
734 INTEL(PM_753J_90, 1200, 908, 600, 812, INTEL_BUS_CLK),
735 INTEL(PM_753K_90, 1200, 892, 600, 812, INTEL_BUS_CLK),
736 INTEL(PM_753L_90, 1200, 876, 600, 812, INTEL_BUS_CLK),
737 INTEL(PM_733JG_90, 1100, 956, 600, 812, INTEL_BUS_CLK),
738 INTEL(PM_733JH_90, 1100, 940, 600, 812, INTEL_BUS_CLK),
739 INTEL(PM_733JI_90, 1100, 924, 600, 812, INTEL_BUS_CLK),
740 INTEL(PM_733JJ_90, 1100, 908, 600, 812, INTEL_BUS_CLK),
741 INTEL(PM_733JK_90, 1100, 892, 600, 812, INTEL_BUS_CLK),
742 INTEL(PM_733JL_90, 1100, 876, 600, 812, INTEL_BUS_CLK),
533 INTEL(PM_733_90, 1100, 940, 600, 812, INTEL_BUS_CLK),
534 INTEL(PM_723_90, 1000, 940, 600, 812, INTEL_BUS_CLK),
535 { NULL, 0, 0, NULL },
536};
537
538static void est_identify(driver_t *driver, device_t parent);
539static int est_features(driver_t *driver, u_int *features);
540static int est_probe(device_t parent);
541static int est_attach(device_t parent);
542static int est_detach(device_t parent);
543static int est_get_info(device_t dev);
544static int est_acpi_info(device_t dev, freq_info **freqs);
545static int est_table_info(device_t dev, uint64_t msr, uint32_t bus_clk,
546 freq_info **freqs);
547static freq_info *est_get_current(freq_info *freq_list);
548static int est_settings(device_t dev, struct cf_setting *sets, int *count);
549static int est_set(device_t dev, const struct cf_setting *set);
550static int est_get(device_t dev, struct cf_setting *set);
551static int est_type(device_t dev, int *type);
552
553static device_method_t est_methods[] = {
554 /* Device interface */
555 DEVMETHOD(device_identify, est_identify),
556 DEVMETHOD(device_probe, est_probe),
557 DEVMETHOD(device_attach, est_attach),
558 DEVMETHOD(device_detach, est_detach),
559
560 /* cpufreq interface */
561 DEVMETHOD(cpufreq_drv_set, est_set),
562 DEVMETHOD(cpufreq_drv_get, est_get),
563 DEVMETHOD(cpufreq_drv_type, est_type),
564 DEVMETHOD(cpufreq_drv_settings, est_settings),
565
566 /* ACPI interface */
567 DEVMETHOD(acpi_get_features, est_features),
568
569 {0, 0}
570};
571
572static driver_t est_driver = {
573 "est",
574 est_methods,
575 sizeof(struct est_softc),
576};
577
578static devclass_t est_devclass;
579DRIVER_MODULE(est, cpu, est_driver, est_devclass, 0, 0);
580
581static int
582est_features(driver_t *driver, u_int *features)
583{
584
585 /* Notify the ACPI CPU that we support direct access to MSRs */
586 *features = ACPI_CAP_PERF_MSRS;
587 return (0);
588}
589
590static void
591est_identify(driver_t *driver, device_t parent)
592{
593 device_t child;
594 u_int p[4];
595
596 /* Make sure we're not being doubly invoked. */
597 if (device_find_child(parent, "est", -1) != NULL)
598 return;
599
600 /* Check that CPUID is supported and the vendor is Intel.*/
601 if (cpu_high == 0 || strcmp(cpu_vendor, GenuineIntel) != 0)
602 return;
603
604 /* Read capability bits and check if the CPU supports EST. */
605 do_cpuid(1, p);
606 if ((p[2] & 0x80) == 0)
607 return;
608
609 /*
610 * We add a child for each CPU since settings must be performed
611 * on each CPU in the SMP case.
612 */
613 child = BUS_ADD_CHILD(parent, 0, "est", -1);
614 if (child == NULL)
615 device_printf(parent, "add est child failed\n");
616}
617
618static int
619est_probe(device_t dev)
620{
621 device_t perf_dev;
622 uint64_t msr;
623 int error, type;
624
625 if (resource_disabled("est", 0))
626 return (ENXIO);
627
628 /*
629 * If the ACPI perf driver has attached and is not just offering
630 * info, let it manage things.
631 */
632 perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
633 if (perf_dev && device_is_attached(perf_dev)) {
634 error = CPUFREQ_DRV_TYPE(perf_dev, &type);
635 if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
636 return (ENXIO);
637 }
638
639 /* Attempt to enable SpeedStep if not currently enabled. */
640 msr = rdmsr(MSR_MISC_ENABLE);
641 if ((msr & MSR_SS_ENABLE) == 0) {
642 wrmsr(MSR_MISC_ENABLE, msr | MSR_SS_ENABLE);
643 if (bootverbose)
644 device_printf(dev, "enabling SpeedStep\n");
645
646 /* Check if the enable failed. */
647 msr = rdmsr(MSR_MISC_ENABLE);
648 if ((msr & MSR_SS_ENABLE) == 0) {
649 device_printf(dev, "failed to enable SpeedStep\n");
650 return (ENXIO);
651 }
652 }
653
654 device_set_desc(dev, "Enhanced SpeedStep Frequency Control");
655 return (0);
656}
657
658static int
659est_attach(device_t dev)
660{
661 struct est_softc *sc;
662
663 sc = device_get_softc(dev);
664 sc->dev = dev;
665
666 /* Check CPU for supported settings. */
667 if (est_get_info(dev))
668 return (ENXIO);
669
670 cpufreq_register(dev);
671 return (0);
672}
673
674static int
675est_detach(device_t dev)
676{
677 struct est_softc *sc;
678
679 sc = device_get_softc(dev);
680 if (sc->acpi_settings)
681 free(sc->freq_list, M_DEVBUF);
682 return (ENXIO);
683}
684
685/*
686 * Probe for supported CPU settings. First, check our static table of
687 * settings. If no match, try using the ones offered by acpi_perf
688 * (i.e., _PSS). We use ACPI second because some systems (IBM R/T40
689 * series) export both legacy SMM IO-based access and direct MSR access
690 * but the direct access specifies invalid values for _PSS.
691 */
692static int
693est_get_info(device_t dev)
694{
695 struct est_softc *sc;
696 uint64_t msr;
697 int error;
698
699 sc = device_get_softc(dev);
700 msr = rdmsr(MSR_PERF_STATUS);
701 error = est_table_info(dev, msr, INTEL_BUS_CLK, &sc->freq_list);
702 if (error)
703 error = est_acpi_info(dev, &sc->freq_list);
704
705 if (error) {
706 printf(
707 "est: CPU supports Enhanced Speedstep, but is not recognized.\n"
708 "est: cpu_vendor %s, msr %0jx\n", cpu_vendor, msr);
709 return (ENXIO);
710 }
711
712 return (0);
713}
714
715static int
716est_acpi_info(device_t dev, freq_info **freqs)
717{
718 struct est_softc *sc;
719 struct cf_setting *sets;
720 freq_info *table;
721 device_t perf_dev;
722 int count, error, i;
723
724 perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
725 if (perf_dev == NULL || !device_is_attached(perf_dev))
726 return (ENXIO);
727
728 /* Fetch settings from acpi_perf. */
729 sc = device_get_softc(dev);
730 table = NULL;
731 sets = malloc(MAX_SETTINGS * sizeof(*sets), M_TEMP, M_NOWAIT);
732 if (sets == NULL)
733 return (ENOMEM);
734 error = CPUFREQ_DRV_SETTINGS(perf_dev, sets, &count);
735 if (error)
736 goto out;
737
738 /* Parse settings into our local table format. */
739 table = malloc((count + 1) * sizeof(freq_info), M_DEVBUF, M_NOWAIT);
740 if (table == NULL) {
741 error = ENOMEM;
742 goto out;
743 }
744 for (i = 0; i < count; i++) {
745 /*
746 * TODO: Figure out validity checks for id16. Linux checks
747 * that the control and status values match.
748 */
749 table[i].freq = sets[i].freq;
750 table[i].volts = sets[i].volts;
751 table[i].id16 = sets[i].spec[0];
752 table[i].power = sets[i].power;
753 }
754
755 /* Mark end of table with a terminator. */
756 bzero(&table[i], sizeof(freq_info));
757
758 sc->acpi_settings = TRUE;
759 *freqs = table;
760 error = 0;
761
762out:
763 if (sets)
764 free(sets, M_TEMP);
765 if (error && table)
766 free(table, M_DEVBUF);
767 return (error);
768}
769
770static int
771est_table_info(device_t dev, uint64_t msr, uint32_t bus_clk, freq_info **freqs)
772{
773 cpu_info *p;
774 uint32_t id;
775
776 /* Find a table which matches (vendor, id, bus_clk). */
777 id = msr >> 32;
778 for (p = ESTprocs; p->id32 != 0; p++) {
779 if (strcmp(p->vendor, cpu_vendor) == 0 && p->id32 == id &&
780 p->bus_clk == bus_clk)
781 break;
782 }
783 if (p->id32 == 0)
784 return (EOPNOTSUPP);
785
786 /* Make sure the current setpoint is valid. */
787 if (est_get_current(p->freqtab) == NULL) {
788 device_printf(dev, "current setting not found in table\n");
789 return (EOPNOTSUPP);
790 }
791
792 *freqs = p->freqtab;
793 return (0);
794}
795
796static freq_info *
797est_get_current(freq_info *freq_list)
798{
799 freq_info *f;
800 int i;
801 uint16_t id16;
802
803 /*
804 * Try a few times to get a valid value. Sometimes, if the CPU
805 * is in the middle of an asynchronous transition (i.e., P4TCC),
806 * we get a temporary invalid result.
807 */
808 for (i = 0; i < 5; i++) {
809 id16 = rdmsr(MSR_PERF_STATUS) & 0xffff;
810 for (f = freq_list; f->id16 != 0; f++) {
811 if (f->id16 == id16)
812 return (f);
813 }
814 DELAY(100);
815 }
816 return (NULL);
817}
818
819static int
820est_settings(device_t dev, struct cf_setting *sets, int *count)
821{
822 struct est_softc *sc;
823 freq_info *f;
824 int i;
825
826 sc = device_get_softc(dev);
827 if (*count < EST_MAX_SETTINGS)
828 return (E2BIG);
829
830 i = 0;
831 for (f = sc->freq_list; f->freq != 0; f++, i++) {
832 sets[i].freq = f->freq;
833 sets[i].volts = f->volts;
834 sets[i].power = f->power;
835 sets[i].lat = EST_TRANS_LAT;
836 sets[i].dev = dev;
837 }
838 *count = i;
839
840 return (0);
841}
842
843static int
844est_set(device_t dev, const struct cf_setting *set)
845{
846 struct est_softc *sc;
847 freq_info *f;
848 uint64_t msr;
849
850 /* Find the setting matching the requested one. */
851 sc = device_get_softc(dev);
852 for (f = sc->freq_list; f->freq != 0; f++) {
853 if (f->freq == set->freq)
854 break;
855 }
856 if (f->freq == 0)
857 return (EINVAL);
858
859 /* Read the current register, mask out the old, set the new id. */
860 msr = rdmsr(MSR_PERF_CTL);
861 msr = (msr & ~0xffff) | f->id16;
862 wrmsr(MSR_PERF_CTL, msr);
863
864 /* Wait a short while for the new setting. XXX Is this necessary? */
865 DELAY(EST_TRANS_LAT);
866
867 return (0);
868}
869
870static int
871est_get(device_t dev, struct cf_setting *set)
872{
873 struct est_softc *sc;
874 freq_info *f;
875
876 sc = device_get_softc(dev);
877 f = est_get_current(sc->freq_list);
878 if (f == NULL)
879 return (ENXIO);
880
881 set->freq = f->freq;
882 set->volts = f->volts;
883 set->power = f->power;
884 set->lat = EST_TRANS_LAT;
885 set->dev = dev;
886 return (0);
887}
888
889static int
890est_type(device_t dev, int *type)
891{
892
893 if (type == NULL)
894 return (EINVAL);
895
896 *type = CPUFREQ_TYPE_ABSOLUTE;
897 return (0);
898}
743 INTEL(PM_733_90, 1100, 940, 600, 812, INTEL_BUS_CLK),
744 INTEL(PM_723_90, 1000, 940, 600, 812, INTEL_BUS_CLK),
745 { NULL, 0, 0, NULL },
746};
747
748static void est_identify(driver_t *driver, device_t parent);
749static int est_features(driver_t *driver, u_int *features);
750static int est_probe(device_t parent);
751static int est_attach(device_t parent);
752static int est_detach(device_t parent);
753static int est_get_info(device_t dev);
754static int est_acpi_info(device_t dev, freq_info **freqs);
755static int est_table_info(device_t dev, uint64_t msr, uint32_t bus_clk,
756 freq_info **freqs);
757static freq_info *est_get_current(freq_info *freq_list);
758static int est_settings(device_t dev, struct cf_setting *sets, int *count);
759static int est_set(device_t dev, const struct cf_setting *set);
760static int est_get(device_t dev, struct cf_setting *set);
761static int est_type(device_t dev, int *type);
762
763static device_method_t est_methods[] = {
764 /* Device interface */
765 DEVMETHOD(device_identify, est_identify),
766 DEVMETHOD(device_probe, est_probe),
767 DEVMETHOD(device_attach, est_attach),
768 DEVMETHOD(device_detach, est_detach),
769
770 /* cpufreq interface */
771 DEVMETHOD(cpufreq_drv_set, est_set),
772 DEVMETHOD(cpufreq_drv_get, est_get),
773 DEVMETHOD(cpufreq_drv_type, est_type),
774 DEVMETHOD(cpufreq_drv_settings, est_settings),
775
776 /* ACPI interface */
777 DEVMETHOD(acpi_get_features, est_features),
778
779 {0, 0}
780};
781
782static driver_t est_driver = {
783 "est",
784 est_methods,
785 sizeof(struct est_softc),
786};
787
788static devclass_t est_devclass;
789DRIVER_MODULE(est, cpu, est_driver, est_devclass, 0, 0);
790
791static int
792est_features(driver_t *driver, u_int *features)
793{
794
795 /* Notify the ACPI CPU that we support direct access to MSRs */
796 *features = ACPI_CAP_PERF_MSRS;
797 return (0);
798}
799
800static void
801est_identify(driver_t *driver, device_t parent)
802{
803 device_t child;
804 u_int p[4];
805
806 /* Make sure we're not being doubly invoked. */
807 if (device_find_child(parent, "est", -1) != NULL)
808 return;
809
810 /* Check that CPUID is supported and the vendor is Intel.*/
811 if (cpu_high == 0 || strcmp(cpu_vendor, GenuineIntel) != 0)
812 return;
813
814 /* Read capability bits and check if the CPU supports EST. */
815 do_cpuid(1, p);
816 if ((p[2] & 0x80) == 0)
817 return;
818
819 /*
820 * We add a child for each CPU since settings must be performed
821 * on each CPU in the SMP case.
822 */
823 child = BUS_ADD_CHILD(parent, 0, "est", -1);
824 if (child == NULL)
825 device_printf(parent, "add est child failed\n");
826}
827
828static int
829est_probe(device_t dev)
830{
831 device_t perf_dev;
832 uint64_t msr;
833 int error, type;
834
835 if (resource_disabled("est", 0))
836 return (ENXIO);
837
838 /*
839 * If the ACPI perf driver has attached and is not just offering
840 * info, let it manage things.
841 */
842 perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
843 if (perf_dev && device_is_attached(perf_dev)) {
844 error = CPUFREQ_DRV_TYPE(perf_dev, &type);
845 if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
846 return (ENXIO);
847 }
848
849 /* Attempt to enable SpeedStep if not currently enabled. */
850 msr = rdmsr(MSR_MISC_ENABLE);
851 if ((msr & MSR_SS_ENABLE) == 0) {
852 wrmsr(MSR_MISC_ENABLE, msr | MSR_SS_ENABLE);
853 if (bootverbose)
854 device_printf(dev, "enabling SpeedStep\n");
855
856 /* Check if the enable failed. */
857 msr = rdmsr(MSR_MISC_ENABLE);
858 if ((msr & MSR_SS_ENABLE) == 0) {
859 device_printf(dev, "failed to enable SpeedStep\n");
860 return (ENXIO);
861 }
862 }
863
864 device_set_desc(dev, "Enhanced SpeedStep Frequency Control");
865 return (0);
866}
867
868static int
869est_attach(device_t dev)
870{
871 struct est_softc *sc;
872
873 sc = device_get_softc(dev);
874 sc->dev = dev;
875
876 /* Check CPU for supported settings. */
877 if (est_get_info(dev))
878 return (ENXIO);
879
880 cpufreq_register(dev);
881 return (0);
882}
883
884static int
885est_detach(device_t dev)
886{
887 struct est_softc *sc;
888
889 sc = device_get_softc(dev);
890 if (sc->acpi_settings)
891 free(sc->freq_list, M_DEVBUF);
892 return (ENXIO);
893}
894
895/*
896 * Probe for supported CPU settings. First, check our static table of
897 * settings. If no match, try using the ones offered by acpi_perf
898 * (i.e., _PSS). We use ACPI second because some systems (IBM R/T40
899 * series) export both legacy SMM IO-based access and direct MSR access
900 * but the direct access specifies invalid values for _PSS.
901 */
902static int
903est_get_info(device_t dev)
904{
905 struct est_softc *sc;
906 uint64_t msr;
907 int error;
908
909 sc = device_get_softc(dev);
910 msr = rdmsr(MSR_PERF_STATUS);
911 error = est_table_info(dev, msr, INTEL_BUS_CLK, &sc->freq_list);
912 if (error)
913 error = est_acpi_info(dev, &sc->freq_list);
914
915 if (error) {
916 printf(
917 "est: CPU supports Enhanced Speedstep, but is not recognized.\n"
918 "est: cpu_vendor %s, msr %0jx\n", cpu_vendor, msr);
919 return (ENXIO);
920 }
921
922 return (0);
923}
924
925static int
926est_acpi_info(device_t dev, freq_info **freqs)
927{
928 struct est_softc *sc;
929 struct cf_setting *sets;
930 freq_info *table;
931 device_t perf_dev;
932 int count, error, i;
933
934 perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
935 if (perf_dev == NULL || !device_is_attached(perf_dev))
936 return (ENXIO);
937
938 /* Fetch settings from acpi_perf. */
939 sc = device_get_softc(dev);
940 table = NULL;
941 sets = malloc(MAX_SETTINGS * sizeof(*sets), M_TEMP, M_NOWAIT);
942 if (sets == NULL)
943 return (ENOMEM);
944 error = CPUFREQ_DRV_SETTINGS(perf_dev, sets, &count);
945 if (error)
946 goto out;
947
948 /* Parse settings into our local table format. */
949 table = malloc((count + 1) * sizeof(freq_info), M_DEVBUF, M_NOWAIT);
950 if (table == NULL) {
951 error = ENOMEM;
952 goto out;
953 }
954 for (i = 0; i < count; i++) {
955 /*
956 * TODO: Figure out validity checks for id16. Linux checks
957 * that the control and status values match.
958 */
959 table[i].freq = sets[i].freq;
960 table[i].volts = sets[i].volts;
961 table[i].id16 = sets[i].spec[0];
962 table[i].power = sets[i].power;
963 }
964
965 /* Mark end of table with a terminator. */
966 bzero(&table[i], sizeof(freq_info));
967
968 sc->acpi_settings = TRUE;
969 *freqs = table;
970 error = 0;
971
972out:
973 if (sets)
974 free(sets, M_TEMP);
975 if (error && table)
976 free(table, M_DEVBUF);
977 return (error);
978}
979
980static int
981est_table_info(device_t dev, uint64_t msr, uint32_t bus_clk, freq_info **freqs)
982{
983 cpu_info *p;
984 uint32_t id;
985
986 /* Find a table which matches (vendor, id, bus_clk). */
987 id = msr >> 32;
988 for (p = ESTprocs; p->id32 != 0; p++) {
989 if (strcmp(p->vendor, cpu_vendor) == 0 && p->id32 == id &&
990 p->bus_clk == bus_clk)
991 break;
992 }
993 if (p->id32 == 0)
994 return (EOPNOTSUPP);
995
996 /* Make sure the current setpoint is valid. */
997 if (est_get_current(p->freqtab) == NULL) {
998 device_printf(dev, "current setting not found in table\n");
999 return (EOPNOTSUPP);
1000 }
1001
1002 *freqs = p->freqtab;
1003 return (0);
1004}
1005
1006static freq_info *
1007est_get_current(freq_info *freq_list)
1008{
1009 freq_info *f;
1010 int i;
1011 uint16_t id16;
1012
1013 /*
1014 * Try a few times to get a valid value. Sometimes, if the CPU
1015 * is in the middle of an asynchronous transition (i.e., P4TCC),
1016 * we get a temporary invalid result.
1017 */
1018 for (i = 0; i < 5; i++) {
1019 id16 = rdmsr(MSR_PERF_STATUS) & 0xffff;
1020 for (f = freq_list; f->id16 != 0; f++) {
1021 if (f->id16 == id16)
1022 return (f);
1023 }
1024 DELAY(100);
1025 }
1026 return (NULL);
1027}
1028
1029static int
1030est_settings(device_t dev, struct cf_setting *sets, int *count)
1031{
1032 struct est_softc *sc;
1033 freq_info *f;
1034 int i;
1035
1036 sc = device_get_softc(dev);
1037 if (*count < EST_MAX_SETTINGS)
1038 return (E2BIG);
1039
1040 i = 0;
1041 for (f = sc->freq_list; f->freq != 0; f++, i++) {
1042 sets[i].freq = f->freq;
1043 sets[i].volts = f->volts;
1044 sets[i].power = f->power;
1045 sets[i].lat = EST_TRANS_LAT;
1046 sets[i].dev = dev;
1047 }
1048 *count = i;
1049
1050 return (0);
1051}
1052
1053static int
1054est_set(device_t dev, const struct cf_setting *set)
1055{
1056 struct est_softc *sc;
1057 freq_info *f;
1058 uint64_t msr;
1059
1060 /* Find the setting matching the requested one. */
1061 sc = device_get_softc(dev);
1062 for (f = sc->freq_list; f->freq != 0; f++) {
1063 if (f->freq == set->freq)
1064 break;
1065 }
1066 if (f->freq == 0)
1067 return (EINVAL);
1068
1069 /* Read the current register, mask out the old, set the new id. */
1070 msr = rdmsr(MSR_PERF_CTL);
1071 msr = (msr & ~0xffff) | f->id16;
1072 wrmsr(MSR_PERF_CTL, msr);
1073
1074 /* Wait a short while for the new setting. XXX Is this necessary? */
1075 DELAY(EST_TRANS_LAT);
1076
1077 return (0);
1078}
1079
1080static int
1081est_get(device_t dev, struct cf_setting *set)
1082{
1083 struct est_softc *sc;
1084 freq_info *f;
1085
1086 sc = device_get_softc(dev);
1087 f = est_get_current(sc->freq_list);
1088 if (f == NULL)
1089 return (ENXIO);
1090
1091 set->freq = f->freq;
1092 set->volts = f->volts;
1093 set->power = f->power;
1094 set->lat = EST_TRANS_LAT;
1095 set->dev = dev;
1096 return (0);
1097}
1098
1099static int
1100est_type(device_t dev, int *type)
1101{
1102
1103 if (type == NULL)
1104 return (EINVAL);
1105
1106 *type = CPUFREQ_TYPE_ABSOLUTE;
1107 return (0);
1108}