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/i386/cpufreq/est.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: ecbdccff61ac0501baed394c9300bea0


[ 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.