xref: /freebsd-src/sys/x86/cpufreq/est.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
132580301SAttilio Rao /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3ebf5747bSPedro F. Giffuni  *
432580301SAttilio Rao  * Copyright (c) 2004 Colin Percival
532580301SAttilio Rao  * Copyright (c) 2005 Nate Lawson
632580301SAttilio Rao  * All rights reserved.
732580301SAttilio Rao  *
832580301SAttilio Rao  * Redistribution and use in source and binary forms, with or without
932580301SAttilio Rao  * modification, are permitted providing that the following conditions
1032580301SAttilio Rao  * are met:
1132580301SAttilio Rao  * 1. Redistributions of source code must retain the above copyright
1232580301SAttilio Rao  *    notice, this list of conditions and the following disclaimer.
1332580301SAttilio Rao  * 2. Redistributions in binary form must reproduce the above copyright
1432580301SAttilio Rao  *    notice, this list of conditions and the following disclaimer in the
1532580301SAttilio Rao  *    documentation and/or other materials provided with the distribution.
1632580301SAttilio Rao  *
1732580301SAttilio Rao  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR``AS IS'' AND ANY EXPRESS OR
1832580301SAttilio Rao  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1932580301SAttilio Rao  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2032580301SAttilio Rao  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2132580301SAttilio Rao  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2232580301SAttilio Rao  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2332580301SAttilio Rao  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2432580301SAttilio Rao  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2532580301SAttilio Rao  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2632580301SAttilio Rao  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2732580301SAttilio Rao  * POSSIBILITY OF SUCH DAMAGE.
2832580301SAttilio Rao  */
2932580301SAttilio Rao 
3032580301SAttilio Rao #include <sys/param.h>
3132580301SAttilio Rao #include <sys/bus.h>
3232580301SAttilio Rao #include <sys/cpu.h>
3332580301SAttilio Rao #include <sys/kernel.h>
3432580301SAttilio Rao #include <sys/malloc.h>
3532580301SAttilio Rao #include <sys/module.h>
3632580301SAttilio Rao #include <sys/smp.h>
3732580301SAttilio Rao #include <sys/systm.h>
3832580301SAttilio Rao 
3932580301SAttilio Rao #include "cpufreq_if.h"
4032580301SAttilio Rao #include <machine/clock.h>
4132580301SAttilio Rao #include <machine/cputypes.h>
4232580301SAttilio Rao #include <machine/md_var.h>
4332580301SAttilio Rao #include <machine/specialreg.h>
4432580301SAttilio Rao 
4532580301SAttilio Rao #include <contrib/dev/acpica/include/acpi.h>
4632580301SAttilio Rao 
4732580301SAttilio Rao #include <dev/acpica/acpivar.h>
4832580301SAttilio Rao #include "acpi_if.h"
4932580301SAttilio Rao 
504577cf37SConrad Meyer #include <x86/cpufreq/hwpstate_intel_internal.h>
514577cf37SConrad Meyer 
5232580301SAttilio Rao /* Status/control registers (from the IA-32 System Programming Guide). */
5332580301SAttilio Rao #define MSR_PERF_STATUS		0x198
5432580301SAttilio Rao #define MSR_PERF_CTL		0x199
5532580301SAttilio Rao 
5632580301SAttilio Rao /* Register and bit for enabling SpeedStep. */
5732580301SAttilio Rao #define MSR_MISC_ENABLE		0x1a0
5832580301SAttilio Rao #define MSR_SS_ENABLE		(1<<16)
5932580301SAttilio Rao 
6032580301SAttilio Rao /* Frequency and MSR control values. */
6132580301SAttilio Rao typedef struct {
6232580301SAttilio Rao 	uint16_t	freq;
6332580301SAttilio Rao 	uint16_t	volts;
6432580301SAttilio Rao 	uint16_t	id16;
6532580301SAttilio Rao 	int		power;
6632580301SAttilio Rao } freq_info;
6732580301SAttilio Rao 
6832580301SAttilio Rao /* Identifying characteristics of a processor and supported frequencies. */
6932580301SAttilio Rao typedef struct {
7032580301SAttilio Rao 	const u_int	vendor_id;
7132580301SAttilio Rao 	uint32_t	id32;
7232580301SAttilio Rao 	freq_info	*freqtab;
73f6e61711SConrad Meyer 	size_t		tablen;
7432580301SAttilio Rao } cpu_info;
7532580301SAttilio Rao 
7632580301SAttilio Rao struct est_softc {
7732580301SAttilio Rao 	device_t	dev;
7832580301SAttilio Rao 	int		acpi_settings;
7932580301SAttilio Rao 	int		msr_settings;
8032580301SAttilio Rao 	freq_info	*freq_list;
81f6e61711SConrad Meyer 	size_t		flist_len;
8232580301SAttilio Rao };
8332580301SAttilio Rao 
8432580301SAttilio Rao /* Convert MHz and mV into IDs for passing to the MSR. */
8532580301SAttilio Rao #define ID16(MHz, mV, bus_clk)				\
8632580301SAttilio Rao 	(((MHz / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
8732580301SAttilio Rao #define ID32(MHz_hi, mV_hi, MHz_lo, mV_lo, bus_clk)	\
8832580301SAttilio Rao 	((ID16(MHz_lo, mV_lo, bus_clk) << 16) | (ID16(MHz_hi, mV_hi, bus_clk)))
8932580301SAttilio Rao 
9032580301SAttilio Rao /* Format for storing IDs in our table. */
9132580301SAttilio Rao #define FREQ_INFO_PWR(MHz, mV, bus_clk, mW)		\
9232580301SAttilio Rao 	{ MHz, mV, ID16(MHz, mV, bus_clk), mW }
9332580301SAttilio Rao #define FREQ_INFO(MHz, mV, bus_clk)			\
9432580301SAttilio Rao 	FREQ_INFO_PWR(MHz, mV, bus_clk, CPUFREQ_VAL_UNKNOWN)
9532580301SAttilio Rao #define INTEL(tab, zhi, vhi, zlo, vlo, bus_clk)		\
96f6e61711SConrad Meyer 	{ CPU_VENDOR_INTEL, ID32(zhi, vhi, zlo, vlo, bus_clk), tab, nitems(tab) }
9732580301SAttilio Rao #define CENTAUR(tab, zhi, vhi, zlo, vlo, bus_clk)	\
98f6e61711SConrad Meyer 	{ CPU_VENDOR_CENTAUR, ID32(zhi, vhi, zlo, vlo, bus_clk), tab, nitems(tab) }
9932580301SAttilio Rao 
10032580301SAttilio Rao static int msr_info_enabled = 0;
10132580301SAttilio Rao TUNABLE_INT("hw.est.msr_info", &msr_info_enabled);
10232580301SAttilio Rao static int strict = -1;
10332580301SAttilio Rao TUNABLE_INT("hw.est.strict", &strict);
10432580301SAttilio Rao 
10532580301SAttilio Rao /* Default bus clock value for Centrino processors. */
10632580301SAttilio Rao #define INTEL_BUS_CLK		100
10732580301SAttilio Rao 
10832580301SAttilio Rao /* XXX Update this if new CPUs have more settings. */
10932580301SAttilio Rao #define EST_MAX_SETTINGS	10
11032580301SAttilio Rao CTASSERT(EST_MAX_SETTINGS <= MAX_SETTINGS);
11132580301SAttilio Rao 
11232580301SAttilio Rao /* Estimate in microseconds of latency for performing a transition. */
11332580301SAttilio Rao #define EST_TRANS_LAT		1000
11432580301SAttilio Rao 
11532580301SAttilio Rao /*
116c5952833SAlexander Motin  * Frequency (MHz) and voltage (mV) settings.
11732580301SAttilio Rao  *
11832580301SAttilio Rao  * Dothan processors have multiple VID#s with different settings for
11932580301SAttilio Rao  * each VID#.  Since we can't uniquely identify this info
12032580301SAttilio Rao  * without undisclosed methods from Intel, we can't support newer
12132580301SAttilio Rao  * processors with this table method.  If ACPI Px states are supported,
12232580301SAttilio Rao  * we get info from them.
123c5952833SAlexander Motin  *
124c5952833SAlexander Motin  * Data from the "Intel Pentium M Processor Datasheet",
125c5952833SAlexander Motin  * Order Number 252612-003, Table 5.
12632580301SAttilio Rao  */
12732580301SAttilio Rao static freq_info PM17_130[] = {
12832580301SAttilio Rao 	/* 130nm 1.70GHz Pentium M */
12932580301SAttilio Rao 	FREQ_INFO(1700, 1484, INTEL_BUS_CLK),
13032580301SAttilio Rao 	FREQ_INFO(1400, 1308, INTEL_BUS_CLK),
13132580301SAttilio Rao 	FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
13232580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
13332580301SAttilio Rao 	FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
13432580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
13532580301SAttilio Rao };
13632580301SAttilio Rao static freq_info PM16_130[] = {
13732580301SAttilio Rao 	/* 130nm 1.60GHz Pentium M */
13832580301SAttilio Rao 	FREQ_INFO(1600, 1484, INTEL_BUS_CLK),
13932580301SAttilio Rao 	FREQ_INFO(1400, 1420, INTEL_BUS_CLK),
14032580301SAttilio Rao 	FREQ_INFO(1200, 1276, INTEL_BUS_CLK),
14132580301SAttilio Rao 	FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
14232580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
14332580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
14432580301SAttilio Rao };
14532580301SAttilio Rao static freq_info PM15_130[] = {
14632580301SAttilio Rao 	/* 130nm 1.50GHz Pentium M */
14732580301SAttilio Rao 	FREQ_INFO(1500, 1484, INTEL_BUS_CLK),
14832580301SAttilio Rao 	FREQ_INFO(1400, 1452, INTEL_BUS_CLK),
14932580301SAttilio Rao 	FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
15032580301SAttilio Rao 	FREQ_INFO(1000, 1228, INTEL_BUS_CLK),
15132580301SAttilio Rao 	FREQ_INFO( 800, 1116, INTEL_BUS_CLK),
15232580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
15332580301SAttilio Rao };
15432580301SAttilio Rao static freq_info PM14_130[] = {
15532580301SAttilio Rao 	/* 130nm 1.40GHz Pentium M */
15632580301SAttilio Rao 	FREQ_INFO(1400, 1484, INTEL_BUS_CLK),
15732580301SAttilio Rao 	FREQ_INFO(1200, 1436, INTEL_BUS_CLK),
15832580301SAttilio Rao 	FREQ_INFO(1000, 1308, INTEL_BUS_CLK),
15932580301SAttilio Rao 	FREQ_INFO( 800, 1180, INTEL_BUS_CLK),
16032580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
16132580301SAttilio Rao };
16232580301SAttilio Rao static freq_info PM13_130[] = {
16332580301SAttilio Rao 	/* 130nm 1.30GHz Pentium M */
16432580301SAttilio Rao 	FREQ_INFO(1300, 1388, INTEL_BUS_CLK),
16532580301SAttilio Rao 	FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
16632580301SAttilio Rao 	FREQ_INFO(1000, 1292, INTEL_BUS_CLK),
16732580301SAttilio Rao 	FREQ_INFO( 800, 1260, INTEL_BUS_CLK),
16832580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
16932580301SAttilio Rao };
17032580301SAttilio Rao static freq_info PM13_LV_130[] = {
17132580301SAttilio Rao 	/* 130nm 1.30GHz Low Voltage Pentium M */
17232580301SAttilio Rao 	FREQ_INFO(1300, 1180, INTEL_BUS_CLK),
17332580301SAttilio Rao 	FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
17432580301SAttilio Rao 	FREQ_INFO(1100, 1100, INTEL_BUS_CLK),
17532580301SAttilio Rao 	FREQ_INFO(1000, 1020, INTEL_BUS_CLK),
17632580301SAttilio Rao 	FREQ_INFO( 900, 1004, INTEL_BUS_CLK),
17732580301SAttilio Rao 	FREQ_INFO( 800,  988, INTEL_BUS_CLK),
17832580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
17932580301SAttilio Rao };
18032580301SAttilio Rao static freq_info PM12_LV_130[] = {
18132580301SAttilio Rao 	/* 130 nm 1.20GHz Low Voltage Pentium M */
18232580301SAttilio Rao 	FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
18332580301SAttilio Rao 	FREQ_INFO(1100, 1164, INTEL_BUS_CLK),
18432580301SAttilio Rao 	FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
18532580301SAttilio Rao 	FREQ_INFO( 900, 1020, INTEL_BUS_CLK),
18632580301SAttilio Rao 	FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
18732580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
18832580301SAttilio Rao };
18932580301SAttilio Rao static freq_info PM11_LV_130[] = {
19032580301SAttilio Rao 	/* 130 nm 1.10GHz Low Voltage Pentium M */
19132580301SAttilio Rao 	FREQ_INFO(1100, 1180, INTEL_BUS_CLK),
19232580301SAttilio Rao 	FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
19332580301SAttilio Rao 	FREQ_INFO( 900, 1100, INTEL_BUS_CLK),
19432580301SAttilio Rao 	FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
19532580301SAttilio Rao 	FREQ_INFO( 600,  956, INTEL_BUS_CLK),
19632580301SAttilio Rao };
19732580301SAttilio Rao static freq_info PM11_ULV_130[] = {
19832580301SAttilio Rao 	/* 130 nm 1.10GHz Ultra Low Voltage Pentium M */
19932580301SAttilio Rao 	FREQ_INFO(1100, 1004, INTEL_BUS_CLK),
20032580301SAttilio Rao 	FREQ_INFO(1000,  988, INTEL_BUS_CLK),
20132580301SAttilio Rao 	FREQ_INFO( 900,  972, INTEL_BUS_CLK),
20232580301SAttilio Rao 	FREQ_INFO( 800,  956, INTEL_BUS_CLK),
20332580301SAttilio Rao 	FREQ_INFO( 600,  844, INTEL_BUS_CLK),
20432580301SAttilio Rao };
20532580301SAttilio Rao static freq_info PM10_ULV_130[] = {
20632580301SAttilio Rao 	/* 130 nm 1.00GHz Ultra Low Voltage Pentium M */
20732580301SAttilio Rao 	FREQ_INFO(1000, 1004, INTEL_BUS_CLK),
20832580301SAttilio Rao 	FREQ_INFO( 900,  988, INTEL_BUS_CLK),
20932580301SAttilio Rao 	FREQ_INFO( 800,  972, INTEL_BUS_CLK),
21032580301SAttilio Rao 	FREQ_INFO( 600,  844, INTEL_BUS_CLK),
21132580301SAttilio Rao };
21232580301SAttilio Rao 
21332580301SAttilio Rao /*
21432580301SAttilio Rao  * Data from "Intel Pentium M Processor on 90nm Process with
215c5952833SAlexander Motin  * 2-MB L2 Cache Datasheet", Order Number 302189-008, Table 5.
21632580301SAttilio Rao  */
21732580301SAttilio Rao static freq_info PM_765A_90[] = {
21832580301SAttilio Rao 	/* 90 nm 2.10GHz Pentium M, VID #A */
21932580301SAttilio Rao 	FREQ_INFO(2100, 1340, INTEL_BUS_CLK),
22032580301SAttilio Rao 	FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
22132580301SAttilio Rao 	FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
22232580301SAttilio Rao 	FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
22332580301SAttilio Rao 	FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
22432580301SAttilio Rao 	FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
22532580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
22632580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
22732580301SAttilio Rao };
22832580301SAttilio Rao static freq_info PM_765B_90[] = {
22932580301SAttilio Rao 	/* 90 nm 2.10GHz Pentium M, VID #B */
23032580301SAttilio Rao 	FREQ_INFO(2100, 1324, INTEL_BUS_CLK),
23132580301SAttilio Rao 	FREQ_INFO(1800, 1260, INTEL_BUS_CLK),
23232580301SAttilio Rao 	FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
23332580301SAttilio Rao 	FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
23432580301SAttilio Rao 	FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
23532580301SAttilio Rao 	FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
23632580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
23732580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
23832580301SAttilio Rao };
23932580301SAttilio Rao static freq_info PM_765C_90[] = {
24032580301SAttilio Rao 	/* 90 nm 2.10GHz Pentium M, VID #C */
24132580301SAttilio Rao 	FREQ_INFO(2100, 1308, INTEL_BUS_CLK),
24232580301SAttilio Rao 	FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
24332580301SAttilio Rao 	FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
24432580301SAttilio Rao 	FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
24532580301SAttilio Rao 	FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
24632580301SAttilio Rao 	FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
24732580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
24832580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
24932580301SAttilio Rao };
25032580301SAttilio Rao static freq_info PM_765E_90[] = {
25132580301SAttilio Rao 	/* 90 nm 2.10GHz Pentium M, VID #E */
25232580301SAttilio Rao 	FREQ_INFO(2100, 1356, INTEL_BUS_CLK),
25332580301SAttilio Rao 	FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
25432580301SAttilio Rao 	FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
25532580301SAttilio Rao 	FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
25632580301SAttilio Rao 	FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
25732580301SAttilio Rao 	FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
25832580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
25932580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
26032580301SAttilio Rao };
26132580301SAttilio Rao static freq_info PM_755A_90[] = {
26232580301SAttilio Rao 	/* 90 nm 2.00GHz Pentium M, VID #A */
26332580301SAttilio Rao 	FREQ_INFO(2000, 1340, INTEL_BUS_CLK),
26432580301SAttilio Rao 	FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
26532580301SAttilio Rao 	FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
26632580301SAttilio Rao 	FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
26732580301SAttilio Rao 	FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
26832580301SAttilio Rao 	FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
26932580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
27032580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
27132580301SAttilio Rao };
27232580301SAttilio Rao static freq_info PM_755B_90[] = {
27332580301SAttilio Rao 	/* 90 nm 2.00GHz Pentium M, VID #B */
27432580301SAttilio Rao 	FREQ_INFO(2000, 1324, INTEL_BUS_CLK),
27532580301SAttilio Rao 	FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
27632580301SAttilio Rao 	FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
27732580301SAttilio Rao 	FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
27832580301SAttilio Rao 	FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
27932580301SAttilio Rao 	FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
28032580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
28132580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
28232580301SAttilio Rao };
28332580301SAttilio Rao static freq_info PM_755C_90[] = {
28432580301SAttilio Rao 	/* 90 nm 2.00GHz Pentium M, VID #C */
28532580301SAttilio Rao 	FREQ_INFO(2000, 1308, INTEL_BUS_CLK),
28632580301SAttilio Rao 	FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
28732580301SAttilio Rao 	FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
28832580301SAttilio Rao 	FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
28932580301SAttilio Rao 	FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
29032580301SAttilio Rao 	FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
29132580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
29232580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
29332580301SAttilio Rao };
29432580301SAttilio Rao static freq_info PM_755D_90[] = {
29532580301SAttilio Rao 	/* 90 nm 2.00GHz Pentium M, VID #D */
29632580301SAttilio Rao 	FREQ_INFO(2000, 1276, INTEL_BUS_CLK),
29732580301SAttilio Rao 	FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
29832580301SAttilio Rao 	FREQ_INFO(1600, 1196, INTEL_BUS_CLK),
29932580301SAttilio Rao 	FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
30032580301SAttilio Rao 	FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
30132580301SAttilio Rao 	FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
30232580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
30332580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
30432580301SAttilio Rao };
30532580301SAttilio Rao static freq_info PM_745A_90[] = {
30632580301SAttilio Rao 	/* 90 nm 1.80GHz Pentium M, VID #A */
30732580301SAttilio Rao 	FREQ_INFO(1800, 1340, INTEL_BUS_CLK),
30832580301SAttilio Rao 	FREQ_INFO(1600, 1292, INTEL_BUS_CLK),
30932580301SAttilio Rao 	FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
31032580301SAttilio Rao 	FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
31132580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
31232580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
31332580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
31432580301SAttilio Rao };
31532580301SAttilio Rao static freq_info PM_745B_90[] = {
31632580301SAttilio Rao 	/* 90 nm 1.80GHz Pentium M, VID #B */
31732580301SAttilio Rao 	FREQ_INFO(1800, 1324, INTEL_BUS_CLK),
31832580301SAttilio Rao 	FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
31932580301SAttilio Rao 	FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
32032580301SAttilio Rao 	FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
32132580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
32232580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
32332580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
32432580301SAttilio Rao };
32532580301SAttilio Rao static freq_info PM_745C_90[] = {
32632580301SAttilio Rao 	/* 90 nm 1.80GHz Pentium M, VID #C */
32732580301SAttilio Rao 	FREQ_INFO(1800, 1308, INTEL_BUS_CLK),
32832580301SAttilio Rao 	FREQ_INFO(1600, 1260, INTEL_BUS_CLK),
32932580301SAttilio Rao 	FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
33032580301SAttilio Rao 	FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
33132580301SAttilio Rao 	FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
33232580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
33332580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
33432580301SAttilio Rao };
33532580301SAttilio Rao static freq_info PM_745D_90[] = {
33632580301SAttilio Rao 	/* 90 nm 1.80GHz Pentium M, VID #D */
33732580301SAttilio Rao 	FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
33832580301SAttilio Rao 	FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
33932580301SAttilio Rao 	FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
34032580301SAttilio Rao 	FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
34132580301SAttilio Rao 	FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
34232580301SAttilio Rao 	FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
34332580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
34432580301SAttilio Rao };
34532580301SAttilio Rao static freq_info PM_735A_90[] = {
34632580301SAttilio Rao 	/* 90 nm 1.70GHz Pentium M, VID #A */
34732580301SAttilio Rao 	FREQ_INFO(1700, 1340, INTEL_BUS_CLK),
34832580301SAttilio Rao 	FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
34932580301SAttilio Rao 	FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
35032580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
35132580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
35232580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
35332580301SAttilio Rao };
35432580301SAttilio Rao static freq_info PM_735B_90[] = {
35532580301SAttilio Rao 	/* 90 nm 1.70GHz Pentium M, VID #B */
35632580301SAttilio Rao 	FREQ_INFO(1700, 1324, INTEL_BUS_CLK),
35732580301SAttilio Rao 	FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
35832580301SAttilio Rao 	FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
35932580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
36032580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
36132580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
36232580301SAttilio Rao };
36332580301SAttilio Rao static freq_info PM_735C_90[] = {
36432580301SAttilio Rao 	/* 90 nm 1.70GHz Pentium M, VID #C */
36532580301SAttilio Rao 	FREQ_INFO(1700, 1308, INTEL_BUS_CLK),
36632580301SAttilio Rao 	FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
36732580301SAttilio Rao 	FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
36832580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
36932580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
37032580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
37132580301SAttilio Rao };
37232580301SAttilio Rao static freq_info PM_735D_90[] = {
37332580301SAttilio Rao 	/* 90 nm 1.70GHz Pentium M, VID #D */
37432580301SAttilio Rao 	FREQ_INFO(1700, 1276, INTEL_BUS_CLK),
37532580301SAttilio Rao 	FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
37632580301SAttilio Rao 	FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
37732580301SAttilio Rao 	FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
37832580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
37932580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
38032580301SAttilio Rao };
38132580301SAttilio Rao static freq_info PM_725A_90[] = {
38232580301SAttilio Rao 	/* 90 nm 1.60GHz Pentium M, VID #A */
38332580301SAttilio Rao 	FREQ_INFO(1600, 1340, INTEL_BUS_CLK),
38432580301SAttilio Rao 	FREQ_INFO(1400, 1276, INTEL_BUS_CLK),
38532580301SAttilio Rao 	FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
38632580301SAttilio Rao 	FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
38732580301SAttilio Rao 	FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
38832580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
38932580301SAttilio Rao };
39032580301SAttilio Rao static freq_info PM_725B_90[] = {
39132580301SAttilio Rao 	/* 90 nm 1.60GHz Pentium M, VID #B */
39232580301SAttilio Rao 	FREQ_INFO(1600, 1324, INTEL_BUS_CLK),
39332580301SAttilio Rao 	FREQ_INFO(1400, 1260, INTEL_BUS_CLK),
39432580301SAttilio Rao 	FREQ_INFO(1200, 1196, INTEL_BUS_CLK),
39532580301SAttilio Rao 	FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
39632580301SAttilio Rao 	FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
39732580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
39832580301SAttilio Rao };
39932580301SAttilio Rao static freq_info PM_725C_90[] = {
40032580301SAttilio Rao 	/* 90 nm 1.60GHz Pentium M, VID #C */
40132580301SAttilio Rao 	FREQ_INFO(1600, 1308, INTEL_BUS_CLK),
40232580301SAttilio Rao 	FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
40332580301SAttilio Rao 	FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
40432580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
40532580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
40632580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
40732580301SAttilio Rao };
40832580301SAttilio Rao static freq_info PM_725D_90[] = {
40932580301SAttilio Rao 	/* 90 nm 1.60GHz Pentium M, VID #D */
41032580301SAttilio Rao 	FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
41132580301SAttilio Rao 	FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
41232580301SAttilio Rao 	FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
41332580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
41432580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
41532580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
41632580301SAttilio Rao };
41732580301SAttilio Rao static freq_info PM_715A_90[] = {
41832580301SAttilio Rao 	/* 90 nm 1.50GHz Pentium M, VID #A */
41932580301SAttilio Rao 	FREQ_INFO(1500, 1340, INTEL_BUS_CLK),
42032580301SAttilio Rao 	FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
42132580301SAttilio Rao 	FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
42232580301SAttilio Rao 	FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
42332580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
42432580301SAttilio Rao };
42532580301SAttilio Rao static freq_info PM_715B_90[] = {
42632580301SAttilio Rao 	/* 90 nm 1.50GHz Pentium M, VID #B */
42732580301SAttilio Rao 	FREQ_INFO(1500, 1324, INTEL_BUS_CLK),
42832580301SAttilio Rao 	FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
42932580301SAttilio Rao 	FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
43032580301SAttilio Rao 	FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
43132580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
43232580301SAttilio Rao };
43332580301SAttilio Rao static freq_info PM_715C_90[] = {
43432580301SAttilio Rao 	/* 90 nm 1.50GHz Pentium M, VID #C */
43532580301SAttilio Rao 	FREQ_INFO(1500, 1308, INTEL_BUS_CLK),
43632580301SAttilio Rao 	FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
43732580301SAttilio Rao 	FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
43832580301SAttilio Rao 	FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
43932580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
44032580301SAttilio Rao };
44132580301SAttilio Rao static freq_info PM_715D_90[] = {
44232580301SAttilio Rao 	/* 90 nm 1.50GHz Pentium M, VID #D */
44332580301SAttilio Rao 	FREQ_INFO(1500, 1276, INTEL_BUS_CLK),
44432580301SAttilio Rao 	FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
44532580301SAttilio Rao 	FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
44632580301SAttilio Rao 	FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
44732580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
44832580301SAttilio Rao };
44932580301SAttilio Rao static freq_info PM_778_90[] = {
45032580301SAttilio Rao 	/* 90 nm 1.60GHz Low Voltage Pentium M */
45132580301SAttilio Rao 	FREQ_INFO(1600, 1116, INTEL_BUS_CLK),
45232580301SAttilio Rao 	FREQ_INFO(1500, 1116, INTEL_BUS_CLK),
45332580301SAttilio Rao 	FREQ_INFO(1400, 1100, INTEL_BUS_CLK),
45432580301SAttilio Rao 	FREQ_INFO(1300, 1084, INTEL_BUS_CLK),
45532580301SAttilio Rao 	FREQ_INFO(1200, 1068, INTEL_BUS_CLK),
45632580301SAttilio Rao 	FREQ_INFO(1100, 1052, INTEL_BUS_CLK),
45732580301SAttilio Rao 	FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
45832580301SAttilio Rao 	FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
45932580301SAttilio Rao 	FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
46032580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
46132580301SAttilio Rao };
46232580301SAttilio Rao static freq_info PM_758_90[] = {
46332580301SAttilio Rao 	/* 90 nm 1.50GHz Low Voltage Pentium M */
46432580301SAttilio Rao 	FREQ_INFO(1500, 1116, INTEL_BUS_CLK),
46532580301SAttilio Rao 	FREQ_INFO(1400, 1116, INTEL_BUS_CLK),
46632580301SAttilio Rao 	FREQ_INFO(1300, 1100, INTEL_BUS_CLK),
46732580301SAttilio Rao 	FREQ_INFO(1200, 1084, INTEL_BUS_CLK),
46832580301SAttilio Rao 	FREQ_INFO(1100, 1068, INTEL_BUS_CLK),
46932580301SAttilio Rao 	FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
47032580301SAttilio Rao 	FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
47132580301SAttilio Rao 	FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
47232580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
47332580301SAttilio Rao };
47432580301SAttilio Rao static freq_info PM_738_90[] = {
47532580301SAttilio Rao 	/* 90 nm 1.40GHz Low Voltage Pentium M */
47632580301SAttilio Rao 	FREQ_INFO(1400, 1116, INTEL_BUS_CLK),
47732580301SAttilio Rao 	FREQ_INFO(1300, 1116, INTEL_BUS_CLK),
47832580301SAttilio Rao 	FREQ_INFO(1200, 1100, INTEL_BUS_CLK),
47932580301SAttilio Rao 	FREQ_INFO(1100, 1068, INTEL_BUS_CLK),
48032580301SAttilio Rao 	FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
48132580301SAttilio Rao 	FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
48232580301SAttilio Rao 	FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
48332580301SAttilio Rao 	FREQ_INFO( 600,  988, INTEL_BUS_CLK),
48432580301SAttilio Rao };
48532580301SAttilio Rao static freq_info PM_773G_90[] = {
48632580301SAttilio Rao 	/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #G */
48732580301SAttilio Rao 	FREQ_INFO(1300,  956, INTEL_BUS_CLK),
48832580301SAttilio Rao 	FREQ_INFO(1200,  940, INTEL_BUS_CLK),
48932580301SAttilio Rao 	FREQ_INFO(1100,  924, INTEL_BUS_CLK),
49032580301SAttilio Rao 	FREQ_INFO(1000,  908, INTEL_BUS_CLK),
49132580301SAttilio Rao 	FREQ_INFO( 900,  876, INTEL_BUS_CLK),
49232580301SAttilio Rao 	FREQ_INFO( 800,  860, INTEL_BUS_CLK),
49332580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
49432580301SAttilio Rao };
49532580301SAttilio Rao static freq_info PM_773H_90[] = {
49632580301SAttilio Rao 	/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #H */
49732580301SAttilio Rao 	FREQ_INFO(1300,  940, INTEL_BUS_CLK),
49832580301SAttilio Rao 	FREQ_INFO(1200,  924, INTEL_BUS_CLK),
49932580301SAttilio Rao 	FREQ_INFO(1100,  908, INTEL_BUS_CLK),
50032580301SAttilio Rao 	FREQ_INFO(1000,  892, INTEL_BUS_CLK),
50132580301SAttilio Rao 	FREQ_INFO( 900,  876, INTEL_BUS_CLK),
50232580301SAttilio Rao 	FREQ_INFO( 800,  860, INTEL_BUS_CLK),
50332580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
50432580301SAttilio Rao };
50532580301SAttilio Rao static freq_info PM_773I_90[] = {
50632580301SAttilio Rao 	/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #I */
50732580301SAttilio Rao 	FREQ_INFO(1300,  924, INTEL_BUS_CLK),
50832580301SAttilio Rao 	FREQ_INFO(1200,  908, INTEL_BUS_CLK),
50932580301SAttilio Rao 	FREQ_INFO(1100,  892, INTEL_BUS_CLK),
51032580301SAttilio Rao 	FREQ_INFO(1000,  876, INTEL_BUS_CLK),
51132580301SAttilio Rao 	FREQ_INFO( 900,  860, INTEL_BUS_CLK),
51232580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
51332580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
51432580301SAttilio Rao };
51532580301SAttilio Rao static freq_info PM_773J_90[] = {
51632580301SAttilio Rao 	/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #J */
51732580301SAttilio Rao 	FREQ_INFO(1300,  908, INTEL_BUS_CLK),
51832580301SAttilio Rao 	FREQ_INFO(1200,  908, INTEL_BUS_CLK),
51932580301SAttilio Rao 	FREQ_INFO(1100,  892, INTEL_BUS_CLK),
52032580301SAttilio Rao 	FREQ_INFO(1000,  876, INTEL_BUS_CLK),
52132580301SAttilio Rao 	FREQ_INFO( 900,  860, INTEL_BUS_CLK),
52232580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
52332580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
52432580301SAttilio Rao };
52532580301SAttilio Rao static freq_info PM_773K_90[] = {
52632580301SAttilio Rao 	/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #K */
52732580301SAttilio Rao 	FREQ_INFO(1300,  892, INTEL_BUS_CLK),
52832580301SAttilio Rao 	FREQ_INFO(1200,  892, INTEL_BUS_CLK),
52932580301SAttilio Rao 	FREQ_INFO(1100,  876, INTEL_BUS_CLK),
53032580301SAttilio Rao 	FREQ_INFO(1000,  860, INTEL_BUS_CLK),
53132580301SAttilio Rao 	FREQ_INFO( 900,  860, INTEL_BUS_CLK),
53232580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
53332580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
53432580301SAttilio Rao };
53532580301SAttilio Rao static freq_info PM_773L_90[] = {
53632580301SAttilio Rao 	/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #L */
53732580301SAttilio Rao 	FREQ_INFO(1300,  876, INTEL_BUS_CLK),
53832580301SAttilio Rao 	FREQ_INFO(1200,  876, INTEL_BUS_CLK),
53932580301SAttilio Rao 	FREQ_INFO(1100,  860, INTEL_BUS_CLK),
54032580301SAttilio Rao 	FREQ_INFO(1000,  860, INTEL_BUS_CLK),
54132580301SAttilio Rao 	FREQ_INFO( 900,  844, INTEL_BUS_CLK),
54232580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
54332580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
54432580301SAttilio Rao };
54532580301SAttilio Rao static freq_info PM_753G_90[] = {
54632580301SAttilio Rao 	/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #G */
54732580301SAttilio Rao 	FREQ_INFO(1200,  956, INTEL_BUS_CLK),
54832580301SAttilio Rao 	FREQ_INFO(1100,  940, INTEL_BUS_CLK),
54932580301SAttilio Rao 	FREQ_INFO(1000,  908, INTEL_BUS_CLK),
55032580301SAttilio Rao 	FREQ_INFO( 900,  892, INTEL_BUS_CLK),
55132580301SAttilio Rao 	FREQ_INFO( 800,  860, INTEL_BUS_CLK),
55232580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
55332580301SAttilio Rao };
55432580301SAttilio Rao static freq_info PM_753H_90[] = {
55532580301SAttilio Rao 	/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #H */
55632580301SAttilio Rao 	FREQ_INFO(1200,  940, INTEL_BUS_CLK),
55732580301SAttilio Rao 	FREQ_INFO(1100,  924, INTEL_BUS_CLK),
55832580301SAttilio Rao 	FREQ_INFO(1000,  908, INTEL_BUS_CLK),
55932580301SAttilio Rao 	FREQ_INFO( 900,  876, INTEL_BUS_CLK),
56032580301SAttilio Rao 	FREQ_INFO( 800,  860, INTEL_BUS_CLK),
56132580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
56232580301SAttilio Rao };
56332580301SAttilio Rao static freq_info PM_753I_90[] = {
56432580301SAttilio Rao 	/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #I */
56532580301SAttilio Rao 	FREQ_INFO(1200,  924, INTEL_BUS_CLK),
56632580301SAttilio Rao 	FREQ_INFO(1100,  908, INTEL_BUS_CLK),
56732580301SAttilio Rao 	FREQ_INFO(1000,  892, INTEL_BUS_CLK),
56832580301SAttilio Rao 	FREQ_INFO( 900,  876, INTEL_BUS_CLK),
56932580301SAttilio Rao 	FREQ_INFO( 800,  860, INTEL_BUS_CLK),
57032580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
57132580301SAttilio Rao };
57232580301SAttilio Rao static freq_info PM_753J_90[] = {
57332580301SAttilio Rao 	/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #J */
57432580301SAttilio Rao 	FREQ_INFO(1200,  908, INTEL_BUS_CLK),
57532580301SAttilio Rao 	FREQ_INFO(1100,  892, INTEL_BUS_CLK),
57632580301SAttilio Rao 	FREQ_INFO(1000,  876, INTEL_BUS_CLK),
57732580301SAttilio Rao 	FREQ_INFO( 900,  860, INTEL_BUS_CLK),
57832580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
57932580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
58032580301SAttilio Rao };
58132580301SAttilio Rao static freq_info PM_753K_90[] = {
58232580301SAttilio Rao 	/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #K */
58332580301SAttilio Rao 	FREQ_INFO(1200,  892, INTEL_BUS_CLK),
58432580301SAttilio Rao 	FREQ_INFO(1100,  892, INTEL_BUS_CLK),
58532580301SAttilio Rao 	FREQ_INFO(1000,  876, INTEL_BUS_CLK),
58632580301SAttilio Rao 	FREQ_INFO( 900,  860, INTEL_BUS_CLK),
58732580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
58832580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
58932580301SAttilio Rao };
59032580301SAttilio Rao static freq_info PM_753L_90[] = {
59132580301SAttilio Rao 	/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #L */
59232580301SAttilio Rao 	FREQ_INFO(1200,  876, INTEL_BUS_CLK),
59332580301SAttilio Rao 	FREQ_INFO(1100,  876, INTEL_BUS_CLK),
59432580301SAttilio Rao 	FREQ_INFO(1000,  860, INTEL_BUS_CLK),
59532580301SAttilio Rao 	FREQ_INFO( 900,  844, INTEL_BUS_CLK),
59632580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
59732580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
59832580301SAttilio Rao };
59932580301SAttilio Rao 
60032580301SAttilio Rao static freq_info PM_733JG_90[] = {
60132580301SAttilio Rao 	/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #G */
60232580301SAttilio Rao 	FREQ_INFO(1100,  956, INTEL_BUS_CLK),
60332580301SAttilio Rao 	FREQ_INFO(1000,  940, INTEL_BUS_CLK),
60432580301SAttilio Rao 	FREQ_INFO( 900,  908, INTEL_BUS_CLK),
60532580301SAttilio Rao 	FREQ_INFO( 800,  876, INTEL_BUS_CLK),
60632580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
60732580301SAttilio Rao };
60832580301SAttilio Rao static freq_info PM_733JH_90[] = {
60932580301SAttilio Rao 	/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #H */
61032580301SAttilio Rao 	FREQ_INFO(1100,  940, INTEL_BUS_CLK),
61132580301SAttilio Rao 	FREQ_INFO(1000,  924, INTEL_BUS_CLK),
61232580301SAttilio Rao 	FREQ_INFO( 900,  892, INTEL_BUS_CLK),
61332580301SAttilio Rao 	FREQ_INFO( 800,  876, INTEL_BUS_CLK),
61432580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
61532580301SAttilio Rao };
61632580301SAttilio Rao static freq_info PM_733JI_90[] = {
61732580301SAttilio Rao 	/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #I */
61832580301SAttilio Rao 	FREQ_INFO(1100,  924, INTEL_BUS_CLK),
61932580301SAttilio Rao 	FREQ_INFO(1000,  908, INTEL_BUS_CLK),
62032580301SAttilio Rao 	FREQ_INFO( 900,  892, INTEL_BUS_CLK),
62132580301SAttilio Rao 	FREQ_INFO( 800,  860, INTEL_BUS_CLK),
62232580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
62332580301SAttilio Rao };
62432580301SAttilio Rao static freq_info PM_733JJ_90[] = {
62532580301SAttilio Rao 	/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #J */
62632580301SAttilio Rao 	FREQ_INFO(1100,  908, INTEL_BUS_CLK),
62732580301SAttilio Rao 	FREQ_INFO(1000,  892, INTEL_BUS_CLK),
62832580301SAttilio Rao 	FREQ_INFO( 900,  876, INTEL_BUS_CLK),
62932580301SAttilio Rao 	FREQ_INFO( 800,  860, INTEL_BUS_CLK),
63032580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
63132580301SAttilio Rao };
63232580301SAttilio Rao static freq_info PM_733JK_90[] = {
63332580301SAttilio Rao 	/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #K */
63432580301SAttilio Rao 	FREQ_INFO(1100,  892, INTEL_BUS_CLK),
63532580301SAttilio Rao 	FREQ_INFO(1000,  876, INTEL_BUS_CLK),
63632580301SAttilio Rao 	FREQ_INFO( 900,  860, INTEL_BUS_CLK),
63732580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
63832580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
63932580301SAttilio Rao };
64032580301SAttilio Rao static freq_info PM_733JL_90[] = {
64132580301SAttilio Rao 	/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #L */
64232580301SAttilio Rao 	FREQ_INFO(1100,  876, INTEL_BUS_CLK),
64332580301SAttilio Rao 	FREQ_INFO(1000,  876, INTEL_BUS_CLK),
64432580301SAttilio Rao 	FREQ_INFO( 900,  860, INTEL_BUS_CLK),
64532580301SAttilio Rao 	FREQ_INFO( 800,  844, INTEL_BUS_CLK),
64632580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
64732580301SAttilio Rao };
64832580301SAttilio Rao static freq_info PM_733_90[] = {
64932580301SAttilio Rao 	/* 90 nm 1.10GHz Ultra Low Voltage Pentium M */
65032580301SAttilio Rao 	FREQ_INFO(1100,  940, INTEL_BUS_CLK),
65132580301SAttilio Rao 	FREQ_INFO(1000,  924, INTEL_BUS_CLK),
65232580301SAttilio Rao 	FREQ_INFO( 900,  892, INTEL_BUS_CLK),
65332580301SAttilio Rao 	FREQ_INFO( 800,  876, INTEL_BUS_CLK),
65432580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
65532580301SAttilio Rao };
65632580301SAttilio Rao static freq_info PM_723_90[] = {
65732580301SAttilio Rao 	/* 90 nm 1.00GHz Ultra Low Voltage Pentium M */
65832580301SAttilio Rao 	FREQ_INFO(1000,  940, INTEL_BUS_CLK),
65932580301SAttilio Rao 	FREQ_INFO( 900,  908, INTEL_BUS_CLK),
66032580301SAttilio Rao 	FREQ_INFO( 800,  876, INTEL_BUS_CLK),
66132580301SAttilio Rao 	FREQ_INFO( 600,  812, INTEL_BUS_CLK),
66232580301SAttilio Rao };
66332580301SAttilio Rao 
66432580301SAttilio Rao /*
66532580301SAttilio Rao  * VIA C7-M 500 MHz FSB, 400 MHz FSB, and ULV variants.
66632580301SAttilio Rao  * Data from the "VIA C7-M Processor BIOS Writer's Guide (v2.17)" datasheet.
66732580301SAttilio Rao  */
66832580301SAttilio Rao static freq_info C7M_795[] = {
66932580301SAttilio Rao 	/* 2.00GHz Centaur C7-M 533 Mhz FSB */
67032580301SAttilio Rao 	FREQ_INFO_PWR(2000, 1148, 133, 20000),
67132580301SAttilio Rao 	FREQ_INFO_PWR(1867, 1132, 133, 18000),
67232580301SAttilio Rao 	FREQ_INFO_PWR(1600, 1100, 133, 15000),
67332580301SAttilio Rao 	FREQ_INFO_PWR(1467, 1052, 133, 13000),
67432580301SAttilio Rao 	FREQ_INFO_PWR(1200, 1004, 133, 10000),
67532580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 133,  7000),
67632580301SAttilio Rao 	FREQ_INFO_PWR( 667,  844, 133,  6000),
67732580301SAttilio Rao 	FREQ_INFO_PWR( 533,  844, 133,  5000),
67832580301SAttilio Rao };
67932580301SAttilio Rao static freq_info C7M_785[] = {
68032580301SAttilio Rao 	/* 1.80GHz Centaur C7-M 533 Mhz FSB */
68132580301SAttilio Rao 	FREQ_INFO_PWR(1867, 1148, 133, 18000),
68232580301SAttilio Rao 	FREQ_INFO_PWR(1600, 1100, 133, 15000),
68332580301SAttilio Rao 	FREQ_INFO_PWR(1467, 1052, 133, 13000),
68432580301SAttilio Rao 	FREQ_INFO_PWR(1200, 1004, 133, 10000),
68532580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 133,  7000),
68632580301SAttilio Rao 	FREQ_INFO_PWR( 667,  844, 133,  6000),
68732580301SAttilio Rao 	FREQ_INFO_PWR( 533,  844, 133,  5000),
68832580301SAttilio Rao };
68932580301SAttilio Rao static freq_info C7M_765[] = {
69032580301SAttilio Rao 	/* 1.60GHz Centaur C7-M 533 Mhz FSB */
69132580301SAttilio Rao 	FREQ_INFO_PWR(1600, 1084, 133, 15000),
69232580301SAttilio Rao 	FREQ_INFO_PWR(1467, 1052, 133, 13000),
69332580301SAttilio Rao 	FREQ_INFO_PWR(1200, 1004, 133, 10000),
69432580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 133,  7000),
69532580301SAttilio Rao 	FREQ_INFO_PWR( 667,  844, 133,  6000),
69632580301SAttilio Rao 	FREQ_INFO_PWR( 533,  844, 133,  5000),
69732580301SAttilio Rao };
69832580301SAttilio Rao 
69932580301SAttilio Rao static freq_info C7M_794[] = {
70032580301SAttilio Rao 	/* 2.00GHz Centaur C7-M 400 Mhz FSB */
70132580301SAttilio Rao 	FREQ_INFO_PWR(2000, 1148, 100, 20000),
70232580301SAttilio Rao 	FREQ_INFO_PWR(1800, 1132, 100, 18000),
70332580301SAttilio Rao 	FREQ_INFO_PWR(1600, 1100, 100, 15000),
70432580301SAttilio Rao 	FREQ_INFO_PWR(1400, 1052, 100, 13000),
70532580301SAttilio Rao 	FREQ_INFO_PWR(1000, 1004, 100, 10000),
70632580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 100,  7000),
70732580301SAttilio Rao 	FREQ_INFO_PWR( 600,  844, 100,  6000),
70832580301SAttilio Rao 	FREQ_INFO_PWR( 400,  844, 100,  5000),
70932580301SAttilio Rao };
71032580301SAttilio Rao static freq_info C7M_784[] = {
71132580301SAttilio Rao 	/* 1.80GHz Centaur C7-M 400 Mhz FSB */
71232580301SAttilio Rao 	FREQ_INFO_PWR(1800, 1148, 100, 18000),
71332580301SAttilio Rao 	FREQ_INFO_PWR(1600, 1100, 100, 15000),
71432580301SAttilio Rao 	FREQ_INFO_PWR(1400, 1052, 100, 13000),
71532580301SAttilio Rao 	FREQ_INFO_PWR(1000, 1004, 100, 10000),
71632580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 100,  7000),
71732580301SAttilio Rao 	FREQ_INFO_PWR( 600,  844, 100,  6000),
71832580301SAttilio Rao 	FREQ_INFO_PWR( 400,  844, 100,  5000),
71932580301SAttilio Rao };
72032580301SAttilio Rao static freq_info C7M_764[] = {
72132580301SAttilio Rao 	/* 1.60GHz Centaur C7-M 400 Mhz FSB */
72232580301SAttilio Rao 	FREQ_INFO_PWR(1600, 1084, 100, 15000),
72332580301SAttilio Rao 	FREQ_INFO_PWR(1400, 1052, 100, 13000),
72432580301SAttilio Rao 	FREQ_INFO_PWR(1000, 1004, 100, 10000),
72532580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 100,  7000),
72632580301SAttilio Rao 	FREQ_INFO_PWR( 600,  844, 100,  6000),
72732580301SAttilio Rao 	FREQ_INFO_PWR( 400,  844, 100,  5000),
72832580301SAttilio Rao };
72932580301SAttilio Rao static freq_info C7M_754[] = {
73032580301SAttilio Rao 	/* 1.50GHz Centaur C7-M 400 Mhz FSB */
73132580301SAttilio Rao 	FREQ_INFO_PWR(1500, 1004, 100, 12000),
73232580301SAttilio Rao 	FREQ_INFO_PWR(1400,  988, 100, 11000),
73332580301SAttilio Rao 	FREQ_INFO_PWR(1000,  940, 100,  9000),
73432580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 100,  7000),
73532580301SAttilio Rao 	FREQ_INFO_PWR( 600,  844, 100,  6000),
73632580301SAttilio Rao 	FREQ_INFO_PWR( 400,  844, 100,  5000),
73732580301SAttilio Rao };
73832580301SAttilio Rao static freq_info C7M_771[] = {
73932580301SAttilio Rao 	/* 1.20GHz Centaur C7-M 400 Mhz FSB */
74032580301SAttilio Rao 	FREQ_INFO_PWR(1200,  860, 100,  7000),
74132580301SAttilio Rao 	FREQ_INFO_PWR(1000,  860, 100,  6000),
74232580301SAttilio Rao 	FREQ_INFO_PWR( 800,  844, 100,  5500),
74332580301SAttilio Rao 	FREQ_INFO_PWR( 600,  844, 100,  5000),
74432580301SAttilio Rao 	FREQ_INFO_PWR( 400,  844, 100,  4000),
74532580301SAttilio Rao };
74632580301SAttilio Rao 
74732580301SAttilio Rao static freq_info C7M_775_ULV[] = {
74832580301SAttilio Rao 	/* 1.50GHz Centaur C7-M ULV */
74932580301SAttilio Rao 	FREQ_INFO_PWR(1500,  956, 100,  7500),
75032580301SAttilio Rao 	FREQ_INFO_PWR(1400,  940, 100,  6000),
75132580301SAttilio Rao 	FREQ_INFO_PWR(1000,  860, 100,  5000),
75232580301SAttilio Rao 	FREQ_INFO_PWR( 800,  828, 100,  2800),
75332580301SAttilio Rao 	FREQ_INFO_PWR( 600,  796, 100,  2500),
75432580301SAttilio Rao 	FREQ_INFO_PWR( 400,  796, 100,  2000),
75532580301SAttilio Rao };
75632580301SAttilio Rao static freq_info C7M_772_ULV[] = {
75732580301SAttilio Rao 	/* 1.20GHz Centaur C7-M ULV */
75832580301SAttilio Rao 	FREQ_INFO_PWR(1200,  844, 100,  5000),
75932580301SAttilio Rao 	FREQ_INFO_PWR(1000,  844, 100,  4000),
76032580301SAttilio Rao 	FREQ_INFO_PWR( 800,  828, 100,  2800),
76132580301SAttilio Rao 	FREQ_INFO_PWR( 600,  796, 100,  2500),
76232580301SAttilio Rao 	FREQ_INFO_PWR( 400,  796, 100,  2000),
76332580301SAttilio Rao };
76432580301SAttilio Rao static freq_info C7M_779_ULV[] = {
76532580301SAttilio Rao 	/* 1.00GHz Centaur C7-M ULV */
76632580301SAttilio Rao 	FREQ_INFO_PWR(1000,  796, 100,  3500),
76732580301SAttilio Rao 	FREQ_INFO_PWR( 800,  796, 100,  2800),
76832580301SAttilio Rao 	FREQ_INFO_PWR( 600,  796, 100,  2500),
76932580301SAttilio Rao 	FREQ_INFO_PWR( 400,  796, 100,  2000),
77032580301SAttilio Rao };
77132580301SAttilio Rao static freq_info C7M_770_ULV[] = {
77232580301SAttilio Rao 	/* 1.00GHz Centaur C7-M ULV */
77332580301SAttilio Rao 	FREQ_INFO_PWR(1000,  844, 100,  5000),
77432580301SAttilio Rao 	FREQ_INFO_PWR( 800,  796, 100,  2800),
77532580301SAttilio Rao 	FREQ_INFO_PWR( 600,  796, 100,  2500),
77632580301SAttilio Rao 	FREQ_INFO_PWR( 400,  796, 100,  2000),
77732580301SAttilio Rao };
77832580301SAttilio Rao 
77932580301SAttilio Rao static cpu_info ESTprocs[] = {
78032580301SAttilio Rao 	INTEL(PM17_130,		1700, 1484, 600, 956, INTEL_BUS_CLK),
78132580301SAttilio Rao 	INTEL(PM16_130,		1600, 1484, 600, 956, INTEL_BUS_CLK),
78232580301SAttilio Rao 	INTEL(PM15_130,		1500, 1484, 600, 956, INTEL_BUS_CLK),
78332580301SAttilio Rao 	INTEL(PM14_130,		1400, 1484, 600, 956, INTEL_BUS_CLK),
78432580301SAttilio Rao 	INTEL(PM13_130,		1300, 1388, 600, 956, INTEL_BUS_CLK),
78532580301SAttilio Rao 	INTEL(PM13_LV_130,	1300, 1180, 600, 956, INTEL_BUS_CLK),
78632580301SAttilio Rao 	INTEL(PM12_LV_130,	1200, 1180, 600, 956, INTEL_BUS_CLK),
78732580301SAttilio Rao 	INTEL(PM11_LV_130,	1100, 1180, 600, 956, INTEL_BUS_CLK),
78832580301SAttilio Rao 	INTEL(PM11_ULV_130,	1100, 1004, 600, 844, INTEL_BUS_CLK),
78932580301SAttilio Rao 	INTEL(PM10_ULV_130,	1000, 1004, 600, 844, INTEL_BUS_CLK),
79032580301SAttilio Rao 	INTEL(PM_765A_90,	2100, 1340, 600, 988, INTEL_BUS_CLK),
79132580301SAttilio Rao 	INTEL(PM_765B_90,	2100, 1324, 600, 988, INTEL_BUS_CLK),
79232580301SAttilio Rao 	INTEL(PM_765C_90,	2100, 1308, 600, 988, INTEL_BUS_CLK),
79332580301SAttilio Rao 	INTEL(PM_765E_90,	2100, 1356, 600, 988, INTEL_BUS_CLK),
79432580301SAttilio Rao 	INTEL(PM_755A_90,	2000, 1340, 600, 988, INTEL_BUS_CLK),
79532580301SAttilio Rao 	INTEL(PM_755B_90,	2000, 1324, 600, 988, INTEL_BUS_CLK),
79632580301SAttilio Rao 	INTEL(PM_755C_90,	2000, 1308, 600, 988, INTEL_BUS_CLK),
79732580301SAttilio Rao 	INTEL(PM_755D_90,	2000, 1276, 600, 988, INTEL_BUS_CLK),
79832580301SAttilio Rao 	INTEL(PM_745A_90,	1800, 1340, 600, 988, INTEL_BUS_CLK),
79932580301SAttilio Rao 	INTEL(PM_745B_90,	1800, 1324, 600, 988, INTEL_BUS_CLK),
80032580301SAttilio Rao 	INTEL(PM_745C_90,	1800, 1308, 600, 988, INTEL_BUS_CLK),
80132580301SAttilio Rao 	INTEL(PM_745D_90,	1800, 1276, 600, 988, INTEL_BUS_CLK),
80232580301SAttilio Rao 	INTEL(PM_735A_90,	1700, 1340, 600, 988, INTEL_BUS_CLK),
80332580301SAttilio Rao 	INTEL(PM_735B_90,	1700, 1324, 600, 988, INTEL_BUS_CLK),
80432580301SAttilio Rao 	INTEL(PM_735C_90,	1700, 1308, 600, 988, INTEL_BUS_CLK),
80532580301SAttilio Rao 	INTEL(PM_735D_90,	1700, 1276, 600, 988, INTEL_BUS_CLK),
80632580301SAttilio Rao 	INTEL(PM_725A_90,	1600, 1340, 600, 988, INTEL_BUS_CLK),
80732580301SAttilio Rao 	INTEL(PM_725B_90,	1600, 1324, 600, 988, INTEL_BUS_CLK),
80832580301SAttilio Rao 	INTEL(PM_725C_90,	1600, 1308, 600, 988, INTEL_BUS_CLK),
80932580301SAttilio Rao 	INTEL(PM_725D_90,	1600, 1276, 600, 988, INTEL_BUS_CLK),
81032580301SAttilio Rao 	INTEL(PM_715A_90,	1500, 1340, 600, 988, INTEL_BUS_CLK),
81132580301SAttilio Rao 	INTEL(PM_715B_90,	1500, 1324, 600, 988, INTEL_BUS_CLK),
81232580301SAttilio Rao 	INTEL(PM_715C_90,	1500, 1308, 600, 988, INTEL_BUS_CLK),
81332580301SAttilio Rao 	INTEL(PM_715D_90,	1500, 1276, 600, 988, INTEL_BUS_CLK),
81432580301SAttilio Rao 	INTEL(PM_778_90,	1600, 1116, 600, 988, INTEL_BUS_CLK),
81532580301SAttilio Rao 	INTEL(PM_758_90,	1500, 1116, 600, 988, INTEL_BUS_CLK),
81632580301SAttilio Rao 	INTEL(PM_738_90,	1400, 1116, 600, 988, INTEL_BUS_CLK),
81732580301SAttilio Rao 	INTEL(PM_773G_90,	1300,  956, 600, 812, INTEL_BUS_CLK),
81832580301SAttilio Rao 	INTEL(PM_773H_90,	1300,  940, 600, 812, INTEL_BUS_CLK),
81932580301SAttilio Rao 	INTEL(PM_773I_90,	1300,  924, 600, 812, INTEL_BUS_CLK),
82032580301SAttilio Rao 	INTEL(PM_773J_90,	1300,  908, 600, 812, INTEL_BUS_CLK),
82132580301SAttilio Rao 	INTEL(PM_773K_90,	1300,  892, 600, 812, INTEL_BUS_CLK),
82232580301SAttilio Rao 	INTEL(PM_773L_90,	1300,  876, 600, 812, INTEL_BUS_CLK),
82332580301SAttilio Rao 	INTEL(PM_753G_90,	1200,  956, 600, 812, INTEL_BUS_CLK),
82432580301SAttilio Rao 	INTEL(PM_753H_90,	1200,  940, 600, 812, INTEL_BUS_CLK),
82532580301SAttilio Rao 	INTEL(PM_753I_90,	1200,  924, 600, 812, INTEL_BUS_CLK),
82632580301SAttilio Rao 	INTEL(PM_753J_90,	1200,  908, 600, 812, INTEL_BUS_CLK),
82732580301SAttilio Rao 	INTEL(PM_753K_90,	1200,  892, 600, 812, INTEL_BUS_CLK),
82832580301SAttilio Rao 	INTEL(PM_753L_90,	1200,  876, 600, 812, INTEL_BUS_CLK),
82932580301SAttilio Rao 	INTEL(PM_733JG_90,	1100,  956, 600, 812, INTEL_BUS_CLK),
83032580301SAttilio Rao 	INTEL(PM_733JH_90,	1100,  940, 600, 812, INTEL_BUS_CLK),
83132580301SAttilio Rao 	INTEL(PM_733JI_90,	1100,  924, 600, 812, INTEL_BUS_CLK),
83232580301SAttilio Rao 	INTEL(PM_733JJ_90,	1100,  908, 600, 812, INTEL_BUS_CLK),
83332580301SAttilio Rao 	INTEL(PM_733JK_90,	1100,  892, 600, 812, INTEL_BUS_CLK),
83432580301SAttilio Rao 	INTEL(PM_733JL_90,	1100,  876, 600, 812, INTEL_BUS_CLK),
83532580301SAttilio Rao 	INTEL(PM_733_90,	1100,  940, 600, 812, INTEL_BUS_CLK),
83632580301SAttilio Rao 	INTEL(PM_723_90,	1000,  940, 600, 812, INTEL_BUS_CLK),
83732580301SAttilio Rao 
83832580301SAttilio Rao 	CENTAUR(C7M_795,	2000, 1148, 533, 844, 133),
83932580301SAttilio Rao 	CENTAUR(C7M_794,	2000, 1148, 400, 844, 100),
84032580301SAttilio Rao 	CENTAUR(C7M_785,	1867, 1148, 533, 844, 133),
84132580301SAttilio Rao 	CENTAUR(C7M_784,	1800, 1148, 400, 844, 100),
84232580301SAttilio Rao 	CENTAUR(C7M_765,	1600, 1084, 533, 844, 133),
84332580301SAttilio Rao 	CENTAUR(C7M_764,	1600, 1084, 400, 844, 100),
84432580301SAttilio Rao 	CENTAUR(C7M_754,	1500, 1004, 400, 844, 100),
84532580301SAttilio Rao 	CENTAUR(C7M_775_ULV,	1500,  956, 400, 796, 100),
84632580301SAttilio Rao 	CENTAUR(C7M_771,	1200,  860, 400, 844, 100),
84732580301SAttilio Rao 	CENTAUR(C7M_772_ULV,	1200,  844, 400, 796, 100),
84832580301SAttilio Rao 	CENTAUR(C7M_779_ULV,	1000,  796, 400, 796, 100),
84932580301SAttilio Rao 	CENTAUR(C7M_770_ULV,	1000,  844, 400, 796, 100),
85032580301SAttilio Rao 	{ 0, 0, NULL },
85132580301SAttilio Rao };
85232580301SAttilio Rao 
85332580301SAttilio Rao static void	est_identify(driver_t *driver, device_t parent);
85432580301SAttilio Rao static int	est_features(driver_t *driver, u_int *features);
85532580301SAttilio Rao static int	est_probe(device_t parent);
85632580301SAttilio Rao static int	est_attach(device_t parent);
85732580301SAttilio Rao static int	est_detach(device_t parent);
85832580301SAttilio Rao static int	est_get_info(device_t dev);
859f6e61711SConrad Meyer static int	est_acpi_info(device_t dev, freq_info **freqs,
860f6e61711SConrad Meyer 		size_t *freqslen);
861f6e61711SConrad Meyer static int	est_table_info(device_t dev, uint64_t msr, freq_info **freqs,
862f6e61711SConrad Meyer 		size_t *freqslen);
863f6e61711SConrad Meyer static int	est_msr_info(device_t dev, uint64_t msr, freq_info **freqs,
864f6e61711SConrad Meyer 		size_t *freqslen);
865f6e61711SConrad Meyer static freq_info *est_get_current(freq_info *freq_list, size_t tablen);
86632580301SAttilio Rao static int	est_settings(device_t dev, struct cf_setting *sets, int *count);
86732580301SAttilio Rao static int	est_set(device_t dev, const struct cf_setting *set);
86832580301SAttilio Rao static int	est_get(device_t dev, struct cf_setting *set);
86932580301SAttilio Rao static int	est_type(device_t dev, int *type);
87032580301SAttilio Rao static int	est_set_id16(device_t dev, uint16_t id16, int need_check);
87132580301SAttilio Rao static void	est_get_id16(uint16_t *id16_p);
87232580301SAttilio Rao 
87332580301SAttilio Rao static device_method_t est_methods[] = {
87432580301SAttilio Rao 	/* Device interface */
87532580301SAttilio Rao 	DEVMETHOD(device_identify,	est_identify),
87632580301SAttilio Rao 	DEVMETHOD(device_probe,		est_probe),
87732580301SAttilio Rao 	DEVMETHOD(device_attach,	est_attach),
87832580301SAttilio Rao 	DEVMETHOD(device_detach,	est_detach),
87932580301SAttilio Rao 
88032580301SAttilio Rao 	/* cpufreq interface */
88132580301SAttilio Rao 	DEVMETHOD(cpufreq_drv_set,	est_set),
88232580301SAttilio Rao 	DEVMETHOD(cpufreq_drv_get,	est_get),
88332580301SAttilio Rao 	DEVMETHOD(cpufreq_drv_type,	est_type),
88432580301SAttilio Rao 	DEVMETHOD(cpufreq_drv_settings,	est_settings),
88532580301SAttilio Rao 
88632580301SAttilio Rao 	/* ACPI interface */
88732580301SAttilio Rao 	DEVMETHOD(acpi_get_features,	est_features),
88832580301SAttilio Rao 	{0, 0}
88932580301SAttilio Rao };
89032580301SAttilio Rao 
89132580301SAttilio Rao static driver_t est_driver = {
89232580301SAttilio Rao 	"est",
89332580301SAttilio Rao 	est_methods,
89432580301SAttilio Rao 	sizeof(struct est_softc),
89532580301SAttilio Rao };
89632580301SAttilio Rao 
897b3407dccSJohn Baldwin DRIVER_MODULE(est, cpu, est_driver, 0, 0);
8984577cf37SConrad Meyer MODULE_DEPEND(est, hwpstate_intel, 1, 1, 1);
89932580301SAttilio Rao 
90032580301SAttilio Rao static int
est_features(driver_t * driver,u_int * features)90132580301SAttilio Rao est_features(driver_t *driver, u_int *features)
90232580301SAttilio Rao {
90332580301SAttilio Rao 
90449abdda9SJung-uk Kim 	/*
90549abdda9SJung-uk Kim 	 * Notify the ACPI CPU that we support direct access to MSRs.
90649abdda9SJung-uk Kim 	 * XXX C1 "I/O then Halt" seems necessary for some broken BIOS.
90749abdda9SJung-uk Kim 	 */
90849abdda9SJung-uk Kim 	*features = ACPI_CAP_PERF_MSRS | ACPI_CAP_C1_IO_HALT;
90932580301SAttilio Rao 	return (0);
91032580301SAttilio Rao }
91132580301SAttilio Rao 
91232580301SAttilio Rao static void
est_identify(driver_t * driver,device_t parent)91332580301SAttilio Rao est_identify(driver_t *driver, device_t parent)
91432580301SAttilio Rao {
91532580301SAttilio Rao 	device_t child;
91632580301SAttilio Rao 
9174577cf37SConrad Meyer 	/*
9184577cf37SConrad Meyer 	 * Defer to hwpstate if it is present. This priority logic
9194577cf37SConrad Meyer 	 * should be replaced with normal newbus probing in the
9204577cf37SConrad Meyer 	 * future.
9214577cf37SConrad Meyer 	 */
9224577cf37SConrad Meyer 	intel_hwpstate_identify(NULL, parent);
9234577cf37SConrad Meyer 	if (device_find_child(parent, "hwpstate_intel", -1) != NULL)
9244577cf37SConrad Meyer 		return;
9254577cf37SConrad Meyer 
92632580301SAttilio Rao 	/* Make sure we're not being doubly invoked. */
92732580301SAttilio Rao 	if (device_find_child(parent, "est", -1) != NULL)
92832580301SAttilio Rao 		return;
92932580301SAttilio Rao 
93032580301SAttilio Rao 	/* Check that CPUID is supported and the vendor is Intel.*/
93132580301SAttilio Rao 	if (cpu_high == 0 || (cpu_vendor_id != CPU_VENDOR_INTEL &&
93232580301SAttilio Rao 	    cpu_vendor_id != CPU_VENDOR_CENTAUR))
93332580301SAttilio Rao 		return;
93432580301SAttilio Rao 
93532580301SAttilio Rao 	/*
93632580301SAttilio Rao 	 * Check if the CPU supports EST.
93732580301SAttilio Rao 	 */
93832580301SAttilio Rao 	if (!(cpu_feature2 & CPUID2_EST))
93932580301SAttilio Rao 		return;
94032580301SAttilio Rao 
94132580301SAttilio Rao 	/*
94232580301SAttilio Rao 	 * We add a child for each CPU since settings must be performed
94332580301SAttilio Rao 	 * on each CPU in the SMP case.
94432580301SAttilio Rao 	 */
945d3a8f98aSAlexander Motin 	child = BUS_ADD_CHILD(parent, 10, "est", device_get_unit(parent));
94632580301SAttilio Rao 	if (child == NULL)
94732580301SAttilio Rao 		device_printf(parent, "add est child failed\n");
94832580301SAttilio Rao }
94932580301SAttilio Rao 
95032580301SAttilio Rao static int
est_probe(device_t dev)95132580301SAttilio Rao est_probe(device_t dev)
95232580301SAttilio Rao {
95332580301SAttilio Rao 	device_t perf_dev;
95432580301SAttilio Rao 	uint64_t msr;
95532580301SAttilio Rao 	int error, type;
95632580301SAttilio Rao 
957a8de37b0SEitan Adler 	if (resource_disabled("est", 0))
958a8de37b0SEitan Adler 		return (ENXIO);
959a8de37b0SEitan Adler 
96032580301SAttilio Rao 	/*
96132580301SAttilio Rao 	 * If the ACPI perf driver has attached and is not just offering
96232580301SAttilio Rao 	 * info, let it manage things.
96332580301SAttilio Rao 	 */
96432580301SAttilio Rao 	perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
96532580301SAttilio Rao 	if (perf_dev && device_is_attached(perf_dev)) {
96632580301SAttilio Rao 		error = CPUFREQ_DRV_TYPE(perf_dev, &type);
96732580301SAttilio Rao 		if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
96832580301SAttilio Rao 			return (ENXIO);
96932580301SAttilio Rao 	}
97032580301SAttilio Rao 
97132580301SAttilio Rao 	/* Attempt to enable SpeedStep if not currently enabled. */
97232580301SAttilio Rao 	msr = rdmsr(MSR_MISC_ENABLE);
97332580301SAttilio Rao 	if ((msr & MSR_SS_ENABLE) == 0) {
97432580301SAttilio Rao 		wrmsr(MSR_MISC_ENABLE, msr | MSR_SS_ENABLE);
97532580301SAttilio Rao 		if (bootverbose)
97632580301SAttilio Rao 			device_printf(dev, "enabling SpeedStep\n");
97732580301SAttilio Rao 
97832580301SAttilio Rao 		/* Check if the enable failed. */
97932580301SAttilio Rao 		msr = rdmsr(MSR_MISC_ENABLE);
98032580301SAttilio Rao 		if ((msr & MSR_SS_ENABLE) == 0) {
98132580301SAttilio Rao 			device_printf(dev, "failed to enable SpeedStep\n");
98232580301SAttilio Rao 			return (ENXIO);
98332580301SAttilio Rao 		}
98432580301SAttilio Rao 	}
98532580301SAttilio Rao 
98632580301SAttilio Rao 	device_set_desc(dev, "Enhanced SpeedStep Frequency Control");
98732580301SAttilio Rao 	return (0);
98832580301SAttilio Rao }
98932580301SAttilio Rao 
99032580301SAttilio Rao static int
est_attach(device_t dev)99132580301SAttilio Rao est_attach(device_t dev)
99232580301SAttilio Rao {
99332580301SAttilio Rao 	struct est_softc *sc;
99432580301SAttilio Rao 
99532580301SAttilio Rao 	sc = device_get_softc(dev);
99632580301SAttilio Rao 	sc->dev = dev;
99732580301SAttilio Rao 
99832580301SAttilio Rao 	/* On SMP system we can't guarantie independent freq setting. */
99932580301SAttilio Rao 	if (strict == -1 && mp_ncpus > 1)
100032580301SAttilio Rao 		strict = 0;
100132580301SAttilio Rao 	/* Check CPU for supported settings. */
100232580301SAttilio Rao 	if (est_get_info(dev))
100332580301SAttilio Rao 		return (ENXIO);
100432580301SAttilio Rao 
100532580301SAttilio Rao 	cpufreq_register(dev);
100632580301SAttilio Rao 	return (0);
100732580301SAttilio Rao }
100832580301SAttilio Rao 
100932580301SAttilio Rao static int
est_detach(device_t dev)101032580301SAttilio Rao est_detach(device_t dev)
101132580301SAttilio Rao {
101232580301SAttilio Rao 	struct est_softc *sc;
101332580301SAttilio Rao 	int error;
101432580301SAttilio Rao 
101532580301SAttilio Rao 	error = cpufreq_unregister(dev);
101632580301SAttilio Rao 	if (error)
101732580301SAttilio Rao 		return (error);
101832580301SAttilio Rao 
101932580301SAttilio Rao 	sc = device_get_softc(dev);
102032580301SAttilio Rao 	if (sc->acpi_settings || sc->msr_settings)
102132580301SAttilio Rao 		free(sc->freq_list, M_DEVBUF);
102232580301SAttilio Rao 	return (0);
102332580301SAttilio Rao }
102432580301SAttilio Rao 
102532580301SAttilio Rao /*
102632580301SAttilio Rao  * Probe for supported CPU settings.  First, check our static table of
102732580301SAttilio Rao  * settings.  If no match, try using the ones offered by acpi_perf
102832580301SAttilio Rao  * (i.e., _PSS).  We use ACPI second because some systems (IBM R/T40
102932580301SAttilio Rao  * series) export both legacy SMM IO-based access and direct MSR access
103032580301SAttilio Rao  * but the direct access specifies invalid values for _PSS.
103132580301SAttilio Rao  */
103232580301SAttilio Rao static int
est_get_info(device_t dev)103332580301SAttilio Rao est_get_info(device_t dev)
103432580301SAttilio Rao {
103532580301SAttilio Rao 	struct est_softc *sc;
103632580301SAttilio Rao 	uint64_t msr;
103732580301SAttilio Rao 	int error;
103832580301SAttilio Rao 
103932580301SAttilio Rao 	sc = device_get_softc(dev);
104032580301SAttilio Rao 	msr = rdmsr(MSR_PERF_STATUS);
1041f6e61711SConrad Meyer 	error = est_table_info(dev, msr, &sc->freq_list, &sc->flist_len);
104232580301SAttilio Rao 	if (error)
1043f6e61711SConrad Meyer 		error = est_acpi_info(dev, &sc->freq_list, &sc->flist_len);
104432580301SAttilio Rao 	if (error)
1045f6e61711SConrad Meyer 		error = est_msr_info(dev, msr, &sc->freq_list, &sc->flist_len);
104632580301SAttilio Rao 
104732580301SAttilio Rao 	if (error) {
104832580301SAttilio Rao 		printf(
104932580301SAttilio Rao 	"est: CPU supports Enhanced Speedstep, but is not recognized.\n"
105032580301SAttilio Rao 	"est: cpu_vendor %s, msr %0jx\n", cpu_vendor, msr);
105132580301SAttilio Rao 		return (ENXIO);
105232580301SAttilio Rao 	}
105332580301SAttilio Rao 
105432580301SAttilio Rao 	return (0);
105532580301SAttilio Rao }
105632580301SAttilio Rao 
105732580301SAttilio Rao static int
est_acpi_info(device_t dev,freq_info ** freqs,size_t * freqslen)1058f6e61711SConrad Meyer est_acpi_info(device_t dev, freq_info **freqs, size_t *freqslen)
105932580301SAttilio Rao {
106032580301SAttilio Rao 	struct est_softc *sc;
106132580301SAttilio Rao 	struct cf_setting *sets;
106232580301SAttilio Rao 	freq_info *table;
106332580301SAttilio Rao 	device_t perf_dev;
106432580301SAttilio Rao 	int count, error, i, j;
106532580301SAttilio Rao 	uint16_t saved_id16;
106632580301SAttilio Rao 
106732580301SAttilio Rao 	perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
106832580301SAttilio Rao 	if (perf_dev == NULL || !device_is_attached(perf_dev))
106932580301SAttilio Rao 		return (ENXIO);
107032580301SAttilio Rao 
107132580301SAttilio Rao 	/* Fetch settings from acpi_perf. */
107232580301SAttilio Rao 	sc = device_get_softc(dev);
107332580301SAttilio Rao 	table = NULL;
107432580301SAttilio Rao 	sets = malloc(MAX_SETTINGS * sizeof(*sets), M_TEMP, M_NOWAIT);
107532580301SAttilio Rao 	if (sets == NULL)
107632580301SAttilio Rao 		return (ENOMEM);
107732580301SAttilio Rao 	count = MAX_SETTINGS;
107832580301SAttilio Rao 	error = CPUFREQ_DRV_SETTINGS(perf_dev, sets, &count);
107932580301SAttilio Rao 	if (error)
108032580301SAttilio Rao 		goto out;
108132580301SAttilio Rao 
108232580301SAttilio Rao 	/* Parse settings into our local table format. */
1083f6e61711SConrad Meyer 	table = malloc(count * sizeof(*table), M_DEVBUF, M_NOWAIT);
108432580301SAttilio Rao 	if (table == NULL) {
108532580301SAttilio Rao 		error = ENOMEM;
108632580301SAttilio Rao 		goto out;
108732580301SAttilio Rao 	}
108832580301SAttilio Rao 	est_get_id16(&saved_id16);
108932580301SAttilio Rao 	for (i = 0, j = 0; i < count; i++) {
109032580301SAttilio Rao 		/*
109132580301SAttilio Rao 		 * Confirm id16 value is correct.
109232580301SAttilio Rao 		 */
109332580301SAttilio Rao 		if (sets[i].freq > 0) {
10945ec55931SAlexander Motin 			error = est_set_id16(dev, sets[i].spec[0], strict);
10955ec55931SAlexander Motin 			if (error != 0) {
109632580301SAttilio Rao 				if (bootverbose)
109732580301SAttilio Rao 					device_printf(dev, "Invalid freq %u, "
109832580301SAttilio Rao 					    "ignored.\n", sets[i].freq);
109932580301SAttilio Rao 				continue;
110032580301SAttilio Rao 			}
110132580301SAttilio Rao 			table[j].freq = sets[i].freq;
110232580301SAttilio Rao 			table[j].volts = sets[i].volts;
110332580301SAttilio Rao 			table[j].id16 = sets[i].spec[0];
110432580301SAttilio Rao 			table[j].power = sets[i].power;
110532580301SAttilio Rao 			++j;
110632580301SAttilio Rao 		}
110732580301SAttilio Rao 	}
110832580301SAttilio Rao 	/* restore saved setting */
110932580301SAttilio Rao 	est_set_id16(dev, saved_id16, 0);
111032580301SAttilio Rao 
111132580301SAttilio Rao 	sc->acpi_settings = TRUE;
111232580301SAttilio Rao 	*freqs = table;
1113f6e61711SConrad Meyer 	*freqslen = j;
111432580301SAttilio Rao 	error = 0;
111532580301SAttilio Rao 
111632580301SAttilio Rao out:
111732580301SAttilio Rao 	if (sets)
111832580301SAttilio Rao 		free(sets, M_TEMP);
111932580301SAttilio Rao 	if (error && table)
112032580301SAttilio Rao 		free(table, M_DEVBUF);
112132580301SAttilio Rao 	return (error);
112232580301SAttilio Rao }
112332580301SAttilio Rao 
112432580301SAttilio Rao static int
est_table_info(device_t dev,uint64_t msr,freq_info ** freqs,size_t * freqslen)1125f6e61711SConrad Meyer est_table_info(device_t dev, uint64_t msr, freq_info **freqs, size_t *freqslen)
112632580301SAttilio Rao {
112732580301SAttilio Rao 	cpu_info *p;
112832580301SAttilio Rao 	uint32_t id;
112932580301SAttilio Rao 
113032580301SAttilio Rao 	/* Find a table which matches (vendor, id32). */
113132580301SAttilio Rao 	id = msr >> 32;
113232580301SAttilio Rao 	for (p = ESTprocs; p->id32 != 0; p++) {
113332580301SAttilio Rao 		if (p->vendor_id == cpu_vendor_id && p->id32 == id)
113432580301SAttilio Rao 			break;
113532580301SAttilio Rao 	}
113632580301SAttilio Rao 	if (p->id32 == 0)
113732580301SAttilio Rao 		return (EOPNOTSUPP);
113832580301SAttilio Rao 
113932580301SAttilio Rao 	/* Make sure the current setpoint is valid. */
1140f6e61711SConrad Meyer 	if (est_get_current(p->freqtab, p->tablen) == NULL) {
114132580301SAttilio Rao 		device_printf(dev, "current setting not found in table\n");
114232580301SAttilio Rao 		return (EOPNOTSUPP);
114332580301SAttilio Rao 	}
114432580301SAttilio Rao 
114532580301SAttilio Rao 	*freqs = p->freqtab;
1146f6e61711SConrad Meyer 	*freqslen = p->tablen;
114732580301SAttilio Rao 	return (0);
114832580301SAttilio Rao }
114932580301SAttilio Rao 
115032580301SAttilio Rao static int
bus_speed_ok(int bus)115132580301SAttilio Rao bus_speed_ok(int bus)
115232580301SAttilio Rao {
115332580301SAttilio Rao 
115432580301SAttilio Rao 	switch (bus) {
115532580301SAttilio Rao 	case 100:
115632580301SAttilio Rao 	case 133:
115732580301SAttilio Rao 	case 333:
115832580301SAttilio Rao 		return (1);
115932580301SAttilio Rao 	default:
116032580301SAttilio Rao 		return (0);
116132580301SAttilio Rao 	}
116232580301SAttilio Rao }
116332580301SAttilio Rao 
116432580301SAttilio Rao /*
116532580301SAttilio Rao  * Flesh out a simple rate table containing the high and low frequencies
116632580301SAttilio Rao  * based on the current clock speed and the upper 32 bits of the MSR.
116732580301SAttilio Rao  */
116832580301SAttilio Rao static int
est_msr_info(device_t dev,uint64_t msr,freq_info ** freqs,size_t * freqslen)1169f6e61711SConrad Meyer est_msr_info(device_t dev, uint64_t msr, freq_info **freqs, size_t *freqslen)
117032580301SAttilio Rao {
117132580301SAttilio Rao 	struct est_softc *sc;
117232580301SAttilio Rao 	freq_info *fp;
117332580301SAttilio Rao 	int bus, freq, volts;
117432580301SAttilio Rao 	uint16_t id;
117532580301SAttilio Rao 
117632580301SAttilio Rao 	if (!msr_info_enabled)
117732580301SAttilio Rao 		return (EOPNOTSUPP);
117832580301SAttilio Rao 
117932580301SAttilio Rao 	/* Figure out the bus clock. */
11803453537fSJung-uk Kim 	freq = atomic_load_acq_64(&tsc_freq) / 1000000;
118132580301SAttilio Rao 	id = msr >> 32;
118232580301SAttilio Rao 	bus = freq / (id >> 8);
118332580301SAttilio Rao 	device_printf(dev, "Guessed bus clock (high) of %d MHz\n", bus);
118432580301SAttilio Rao 	if (!bus_speed_ok(bus)) {
118532580301SAttilio Rao 		/* We may be running on the low frequency. */
118632580301SAttilio Rao 		id = msr >> 48;
118732580301SAttilio Rao 		bus = freq / (id >> 8);
118832580301SAttilio Rao 		device_printf(dev, "Guessed bus clock (low) of %d MHz\n", bus);
118932580301SAttilio Rao 		if (!bus_speed_ok(bus))
119032580301SAttilio Rao 			return (EOPNOTSUPP);
119132580301SAttilio Rao 
119232580301SAttilio Rao 		/* Calculate high frequency. */
119332580301SAttilio Rao 		id = msr >> 32;
119432580301SAttilio Rao 		freq = ((id >> 8) & 0xff) * bus;
119532580301SAttilio Rao 	}
119632580301SAttilio Rao 
119732580301SAttilio Rao 	/* Fill out a new freq table containing just the high and low freqs. */
119832580301SAttilio Rao 	sc = device_get_softc(dev);
1199f6e61711SConrad Meyer 	fp = malloc(sizeof(freq_info) * 2, M_DEVBUF, M_WAITOK | M_ZERO);
120032580301SAttilio Rao 
120132580301SAttilio Rao 	/* First, the high frequency. */
120232580301SAttilio Rao 	volts = id & 0xff;
120332580301SAttilio Rao 	if (volts != 0) {
120432580301SAttilio Rao 		volts <<= 4;
120532580301SAttilio Rao 		volts += 700;
120632580301SAttilio Rao 	}
120732580301SAttilio Rao 	fp[0].freq = freq;
120832580301SAttilio Rao 	fp[0].volts = volts;
120932580301SAttilio Rao 	fp[0].id16 = id;
121032580301SAttilio Rao 	fp[0].power = CPUFREQ_VAL_UNKNOWN;
121132580301SAttilio Rao 	device_printf(dev, "Guessed high setting of %d MHz @ %d Mv\n", freq,
121232580301SAttilio Rao 	    volts);
121332580301SAttilio Rao 
121432580301SAttilio Rao 	/* Second, the low frequency. */
121532580301SAttilio Rao 	id = msr >> 48;
121632580301SAttilio Rao 	freq = ((id >> 8) & 0xff) * bus;
121732580301SAttilio Rao 	volts = id & 0xff;
121832580301SAttilio Rao 	if (volts != 0) {
121932580301SAttilio Rao 		volts <<= 4;
122032580301SAttilio Rao 		volts += 700;
122132580301SAttilio Rao 	}
122232580301SAttilio Rao 	fp[1].freq = freq;
122332580301SAttilio Rao 	fp[1].volts = volts;
122432580301SAttilio Rao 	fp[1].id16 = id;
122532580301SAttilio Rao 	fp[1].power = CPUFREQ_VAL_UNKNOWN;
122632580301SAttilio Rao 	device_printf(dev, "Guessed low setting of %d MHz @ %d Mv\n", freq,
122732580301SAttilio Rao 	    volts);
122832580301SAttilio Rao 
122932580301SAttilio Rao 	/* Table is already terminated due to M_ZERO. */
123032580301SAttilio Rao 	sc->msr_settings = TRUE;
123132580301SAttilio Rao 	*freqs = fp;
1232f6e61711SConrad Meyer 	*freqslen = 2;
123332580301SAttilio Rao 	return (0);
123432580301SAttilio Rao }
123532580301SAttilio Rao 
123632580301SAttilio Rao static void
est_get_id16(uint16_t * id16_p)123732580301SAttilio Rao est_get_id16(uint16_t *id16_p)
123832580301SAttilio Rao {
123932580301SAttilio Rao 	*id16_p = rdmsr(MSR_PERF_STATUS) & 0xffff;
124032580301SAttilio Rao }
124132580301SAttilio Rao 
124232580301SAttilio Rao static int
est_set_id16(device_t dev,uint16_t id16,int need_check)124332580301SAttilio Rao est_set_id16(device_t dev, uint16_t id16, int need_check)
124432580301SAttilio Rao {
124532580301SAttilio Rao 	uint64_t msr;
124632580301SAttilio Rao 	uint16_t new_id16;
124732580301SAttilio Rao 	int ret = 0;
124832580301SAttilio Rao 
124932580301SAttilio Rao 	/* Read the current register, mask out the old, set the new id. */
125032580301SAttilio Rao 	msr = rdmsr(MSR_PERF_CTL);
125132580301SAttilio Rao 	msr = (msr & ~0xffff) | id16;
125232580301SAttilio Rao 	wrmsr(MSR_PERF_CTL, msr);
125332580301SAttilio Rao 
125432580301SAttilio Rao 	if  (need_check) {
12559d75ca28SAlexander Motin 		/* Wait a short while and read the new status. */
12569d75ca28SAlexander Motin 		DELAY(EST_TRANS_LAT);
125732580301SAttilio Rao 		est_get_id16(&new_id16);
125832580301SAttilio Rao 		if (new_id16 != id16) {
125932580301SAttilio Rao 			if (bootverbose)
126032580301SAttilio Rao 				device_printf(dev, "Invalid id16 (set, cur) "
126132580301SAttilio Rao 				    "= (%u, %u)\n", id16, new_id16);
126232580301SAttilio Rao 			ret = ENXIO;
126332580301SAttilio Rao 		}
126432580301SAttilio Rao 	}
126532580301SAttilio Rao 	return (ret);
126632580301SAttilio Rao }
126732580301SAttilio Rao 
126832580301SAttilio Rao static freq_info *
est_get_current(freq_info * freq_list,size_t tablen)1269f6e61711SConrad Meyer est_get_current(freq_info *freq_list, size_t tablen)
127032580301SAttilio Rao {
127132580301SAttilio Rao 	freq_info *f;
127232580301SAttilio Rao 	int i;
127332580301SAttilio Rao 	uint16_t id16;
127432580301SAttilio Rao 
127532580301SAttilio Rao 	/*
127632580301SAttilio Rao 	 * Try a few times to get a valid value.  Sometimes, if the CPU
127732580301SAttilio Rao 	 * is in the middle of an asynchronous transition (i.e., P4TCC),
127832580301SAttilio Rao 	 * we get a temporary invalid result.
127932580301SAttilio Rao 	 */
128032580301SAttilio Rao 	for (i = 0; i < 5; i++) {
128132580301SAttilio Rao 		est_get_id16(&id16);
1282f6e61711SConrad Meyer 		for (f = freq_list; f < freq_list + tablen; f++) {
128332580301SAttilio Rao 			if (f->id16 == id16)
128432580301SAttilio Rao 				return (f);
128532580301SAttilio Rao 		}
128632580301SAttilio Rao 		DELAY(100);
128732580301SAttilio Rao 	}
128832580301SAttilio Rao 	return (NULL);
128932580301SAttilio Rao }
129032580301SAttilio Rao 
129132580301SAttilio Rao static int
est_settings(device_t dev,struct cf_setting * sets,int * count)129232580301SAttilio Rao est_settings(device_t dev, struct cf_setting *sets, int *count)
129332580301SAttilio Rao {
129432580301SAttilio Rao 	struct est_softc *sc;
129532580301SAttilio Rao 	freq_info *f;
129632580301SAttilio Rao 	int i;
129732580301SAttilio Rao 
129832580301SAttilio Rao 	sc = device_get_softc(dev);
129932580301SAttilio Rao 	if (*count < EST_MAX_SETTINGS)
130032580301SAttilio Rao 		return (E2BIG);
130132580301SAttilio Rao 
130232580301SAttilio Rao 	i = 0;
1303f6e61711SConrad Meyer 	for (f = sc->freq_list; f < sc->freq_list + sc->flist_len; f++, i++) {
130432580301SAttilio Rao 		sets[i].freq = f->freq;
130532580301SAttilio Rao 		sets[i].volts = f->volts;
130632580301SAttilio Rao 		sets[i].power = f->power;
130732580301SAttilio Rao 		sets[i].lat = EST_TRANS_LAT;
130832580301SAttilio Rao 		sets[i].dev = dev;
130932580301SAttilio Rao 	}
131032580301SAttilio Rao 	*count = i;
131132580301SAttilio Rao 
131232580301SAttilio Rao 	return (0);
131332580301SAttilio Rao }
131432580301SAttilio Rao 
131532580301SAttilio Rao static int
est_set(device_t dev,const struct cf_setting * set)131632580301SAttilio Rao est_set(device_t dev, const struct cf_setting *set)
131732580301SAttilio Rao {
131832580301SAttilio Rao 	struct est_softc *sc;
131932580301SAttilio Rao 	freq_info *f;
132032580301SAttilio Rao 
132132580301SAttilio Rao 	/* Find the setting matching the requested one. */
132232580301SAttilio Rao 	sc = device_get_softc(dev);
1323f6e61711SConrad Meyer 	for (f = sc->freq_list; f < sc->freq_list + sc->flist_len; f++) {
132432580301SAttilio Rao 		if (f->freq == set->freq)
132532580301SAttilio Rao 			break;
132632580301SAttilio Rao 	}
132732580301SAttilio Rao 	if (f->freq == 0)
132832580301SAttilio Rao 		return (EINVAL);
132932580301SAttilio Rao 
133032580301SAttilio Rao 	/* Read the current register, mask out the old, set the new id. */
133132580301SAttilio Rao 	est_set_id16(dev, f->id16, 0);
133232580301SAttilio Rao 
133332580301SAttilio Rao 	return (0);
133432580301SAttilio Rao }
133532580301SAttilio Rao 
133632580301SAttilio Rao static int
est_get(device_t dev,struct cf_setting * set)133732580301SAttilio Rao est_get(device_t dev, struct cf_setting *set)
133832580301SAttilio Rao {
133932580301SAttilio Rao 	struct est_softc *sc;
134032580301SAttilio Rao 	freq_info *f;
134132580301SAttilio Rao 
134232580301SAttilio Rao 	sc = device_get_softc(dev);
1343f6e61711SConrad Meyer 	f = est_get_current(sc->freq_list, sc->flist_len);
134432580301SAttilio Rao 	if (f == NULL)
134532580301SAttilio Rao 		return (ENXIO);
134632580301SAttilio Rao 
134732580301SAttilio Rao 	set->freq = f->freq;
134832580301SAttilio Rao 	set->volts = f->volts;
134932580301SAttilio Rao 	set->power = f->power;
135032580301SAttilio Rao 	set->lat = EST_TRANS_LAT;
135132580301SAttilio Rao 	set->dev = dev;
135232580301SAttilio Rao 	return (0);
135332580301SAttilio Rao }
135432580301SAttilio Rao 
135532580301SAttilio Rao static int
est_type(device_t dev,int * type)135632580301SAttilio Rao est_type(device_t dev, int *type)
135732580301SAttilio Rao {
135832580301SAttilio Rao 
135932580301SAttilio Rao 	if (type == NULL)
136032580301SAttilio Rao 		return (EINVAL);
136132580301SAttilio Rao 
136232580301SAttilio Rao 	*type = CPUFREQ_TYPE_ABSOLUTE;
136332580301SAttilio Rao 	return (0);
136432580301SAttilio Rao }
1365