The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/x86/cpufreq/est.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 5a226f72d1344329fd7c794efb18d887


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.