linux/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
<<
>>
Prefs
   1/*
   2 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
   3 *
   4 *  Licensed under the terms of the GNU GPL License version 2.
   5 *
   6 *  Library for common functions for Intel SpeedStep v.1 and v.2 support
   7 *
   8 *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/moduleparam.h>
  14#include <linux/init.h>
  15#include <linux/cpufreq.h>
  16#include <linux/slab.h>
  17
  18#include <asm/msr.h>
  19#include <asm/tsc.h>
  20#include "speedstep-lib.h"
  21
  22#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
  23                "speedstep-lib", msg)
  24
  25#define PFX "speedstep-lib: "
  26
  27#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
  28static int relaxed_check;
  29#else
  30#define relaxed_check 0
  31#endif
  32
  33/*********************************************************************
  34 *                   GET PROCESSOR CORE SPEED IN KHZ                 *
  35 *********************************************************************/
  36
  37static unsigned int pentium3_get_frequency(unsigned int processor)
  38{
  39        /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
  40        struct {
  41                unsigned int ratio;     /* Frequency Multiplier (x10) */
  42                u8 bitmap;              /* power on configuration bits
  43                                        [27, 25:22] (in MSR 0x2a) */
  44        } msr_decode_mult[] = {
  45                { 30, 0x01 },
  46                { 35, 0x05 },
  47                { 40, 0x02 },
  48                { 45, 0x06 },
  49                { 50, 0x00 },
  50                { 55, 0x04 },
  51                { 60, 0x0b },
  52                { 65, 0x0f },
  53                { 70, 0x09 },
  54                { 75, 0x0d },
  55                { 80, 0x0a },
  56                { 85, 0x26 },
  57                { 90, 0x20 },
  58                { 100, 0x2b },
  59                { 0, 0xff }     /* error or unknown value */
  60        };
  61
  62        /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
  63        struct {
  64                unsigned int value;     /* Front Side Bus speed in MHz */
  65                u8 bitmap;              /* power on configuration bits [18: 19]
  66                                        (in MSR 0x2a) */
  67        } msr_decode_fsb[] = {
  68                {  66, 0x0 },
  69                { 100, 0x2 },
  70                { 133, 0x1 },
  71                {   0, 0xff}
  72        };
  73
  74        u32 msr_lo, msr_tmp;
  75        int i = 0, j = 0;
  76
  77        /* read MSR 0x2a - we only need the low 32 bits */
  78        rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
  79        dprintk("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
  80        msr_tmp = msr_lo;
  81
  82        /* decode the FSB */
  83        msr_tmp &= 0x00c0000;
  84        msr_tmp >>= 18;
  85        while (msr_tmp != msr_decode_fsb[i].bitmap) {
  86                if (msr_decode_fsb[i].bitmap == 0xff)
  87                        return 0;
  88                i++;
  89        }
  90
  91        /* decode the multiplier */
  92        if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) {
  93                dprintk("workaround for early PIIIs\n");
  94                msr_lo &= 0x03c00000;
  95        } else
  96                msr_lo &= 0x0bc00000;
  97        msr_lo >>= 22;
  98        while (msr_lo != msr_decode_mult[j].bitmap) {
  99                if (msr_decode_mult[j].bitmap == 0xff)
 100                        return 0;
 101                j++;
 102        }
 103
 104        dprintk("speed is %u\n",
 105                (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
 106
 107        return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100;
 108}
 109
 110
 111static unsigned int pentiumM_get_frequency(void)
 112{
 113        u32 msr_lo, msr_tmp;
 114
 115        rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
 116        dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
 117
 118        /* see table B-2 of 24547212.pdf */
 119        if (msr_lo & 0x00040000) {
 120                printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n",
 121                                msr_lo, msr_tmp);
 122                return 0;
 123        }
 124
 125        msr_tmp = (msr_lo >> 22) & 0x1f;
 126        dprintk("bits 22-26 are 0x%x, speed is %u\n",
 127                        msr_tmp, (msr_tmp * 100 * 1000));
 128
 129        return msr_tmp * 100 * 1000;
 130}
 131
 132static unsigned int pentium_core_get_frequency(void)
 133{
 134        u32 fsb = 0;
 135        u32 msr_lo, msr_tmp;
 136        int ret;
 137
 138        rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
 139        /* see table B-2 of 25366920.pdf */
 140        switch (msr_lo & 0x07) {
 141        case 5:
 142                fsb = 100000;
 143                break;
 144        case 1:
 145                fsb = 133333;
 146                break;
 147        case 3:
 148                fsb = 166667;
 149                break;
 150        case 2:
 151                fsb = 200000;
 152                break;
 153        case 0:
 154                fsb = 266667;
 155                break;
 156        case 4:
 157                fsb = 333333;
 158                break;
 159        default:
 160                printk(KERN_ERR "PCORE - MSR_FSB_FREQ undefined value");
 161        }
 162
 163        rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
 164        dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n",
 165                        msr_lo, msr_tmp);
 166
 167        msr_tmp = (msr_lo >> 22) & 0x1f;
 168        dprintk("bits 22-26 are 0x%x, speed is %u\n",
 169                        msr_tmp, (msr_tmp * fsb));
 170
 171        ret = (msr_tmp * fsb);
 172        return ret;
 173}
 174
 175
 176static unsigned int pentium4_get_frequency(void)
 177{
 178        struct cpuinfo_x86 *c = &boot_cpu_data;
 179        u32 msr_lo, msr_hi, mult;
 180        unsigned int fsb = 0;
 181        unsigned int ret;
 182        u8 fsb_code;
 183
 184        /* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency
 185         * to System Bus Frequency Ratio Field in the Processor Frequency
 186         * Configuration Register of the MSR. Therefore the current
 187         * frequency cannot be calculated and has to be measured.
 188         */
 189        if (c->x86_model < 2)
 190                return cpu_khz;
 191
 192        rdmsr(0x2c, msr_lo, msr_hi);
 193
 194        dprintk("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);
 195
 196        /* decode the FSB: see IA-32 Intel (C) Architecture Software
 197         * Developer's Manual, Volume 3: System Prgramming Guide,
 198         * revision #12 in Table B-1: MSRs in the Pentium 4 and
 199         * Intel Xeon Processors, on page B-4 and B-5.
 200         */
 201        fsb_code = (msr_lo >> 16) & 0x7;
 202        switch (fsb_code) {
 203        case 0:
 204                fsb = 100 * 1000;
 205                break;
 206        case 1:
 207                fsb = 13333 * 10;
 208                break;
 209        case 2:
 210                fsb = 200 * 1000;
 211                break;
 212        }
 213
 214        if (!fsb)
 215                printk(KERN_DEBUG PFX "couldn't detect FSB speed. "
 216                                "Please send an e-mail to <linux@brodo.de>\n");
 217
 218        /* Multiplier. */
 219        mult = msr_lo >> 24;
 220
 221        dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n",
 222                        fsb, mult, (fsb * mult));
 223
 224        ret = (fsb * mult);
 225        return ret;
 226}
 227
 228
 229/* Warning: may get called from smp_call_function_single. */
 230unsigned int speedstep_get_frequency(unsigned int processor)
 231{
 232        switch (processor) {
 233        case SPEEDSTEP_CPU_PCORE:
 234                return pentium_core_get_frequency();
 235        case SPEEDSTEP_CPU_PM:
 236                return pentiumM_get_frequency();
 237        case SPEEDSTEP_CPU_P4D:
 238        case SPEEDSTEP_CPU_P4M:
 239                return pentium4_get_frequency();
 240        case SPEEDSTEP_CPU_PIII_T:
 241        case SPEEDSTEP_CPU_PIII_C:
 242        case SPEEDSTEP_CPU_PIII_C_EARLY:
 243                return pentium3_get_frequency(processor);
 244        default:
 245                return 0;
 246        };
 247        return 0;
 248}
 249EXPORT_SYMBOL_GPL(speedstep_get_frequency);
 250
 251
 252/*********************************************************************
 253 *                 DETECT SPEEDSTEP-CAPABLE PROCESSOR                *
 254 *********************************************************************/
 255
 256unsigned int speedstep_detect_processor(void)
 257{
 258        struct cpuinfo_x86 *c = &cpu_data(0);
 259        u32 ebx, msr_lo, msr_hi;
 260
 261        dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
 262
 263        if ((c->x86_vendor != X86_VENDOR_INTEL) ||
 264            ((c->x86 != 6) && (c->x86 != 0xF)))
 265                return 0;
 266
 267        if (c->x86 == 0xF) {
 268                /* Intel Mobile Pentium 4-M
 269                 * or Intel Mobile Pentium 4 with 533 MHz FSB */
 270                if (c->x86_model != 2)
 271                        return 0;
 272
 273                ebx = cpuid_ebx(0x00000001);
 274                ebx &= 0x000000FF;
 275
 276                dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask);
 277
 278                switch (c->x86_mask) {
 279                case 4:
 280                        /*
 281                         * B-stepping [M-P4-M]
 282                         * sample has ebx = 0x0f, production has 0x0e.
 283                         */
 284                        if ((ebx == 0x0e) || (ebx == 0x0f))
 285                                return SPEEDSTEP_CPU_P4M;
 286                        break;
 287                case 7:
 288                        /*
 289                         * C-stepping [M-P4-M]
 290                         * needs to have ebx=0x0e, else it's a celeron:
 291                         * cf. 25130917.pdf / page 7, footnote 5 even
 292                         * though 25072120.pdf / page 7 doesn't say
 293                         * samples are only of B-stepping...
 294                         */
 295                        if (ebx == 0x0e)
 296                                return SPEEDSTEP_CPU_P4M;
 297                        break;
 298                case 9:
 299                        /*
 300                         * D-stepping [M-P4-M or M-P4/533]
 301                         *
 302                         * this is totally strange: CPUID 0x0F29 is
 303                         * used by M-P4-M, M-P4/533 and(!) Celeron CPUs.
 304                         * The latter need to be sorted out as they don't
 305                         * support speedstep.
 306                         * Celerons with CPUID 0x0F29 may have either
 307                         * ebx=0x8 or 0xf -- 25130917.pdf doesn't say anything
 308                         * specific.
 309                         * M-P4-Ms may have either ebx=0xe or 0xf [see above]
 310                         * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
 311                         * also, M-P4M HTs have ebx=0x8, too
 312                         * For now, they are distinguished by the model_id
 313                         * string
 314                         */
 315                        if ((ebx == 0x0e) ||
 316                                (strstr(c->x86_model_id,
 317                                    "Mobile Intel(R) Pentium(R) 4") != NULL))
 318                                return SPEEDSTEP_CPU_P4M;
 319                        break;
 320                default:
 321                        break;
 322                }
 323                return 0;
 324        }
 325
 326        switch (c->x86_model) {
 327        case 0x0B: /* Intel PIII [Tualatin] */
 328                /* cpuid_ebx(1) is 0x04 for desktop PIII,
 329                 * 0x06 for mobile PIII-M */
 330                ebx = cpuid_ebx(0x00000001);
 331                dprintk("ebx is %x\n", ebx);
 332
 333                ebx &= 0x000000FF;
 334
 335                if (ebx != 0x06)
 336                        return 0;
 337
 338                /* So far all PIII-M processors support SpeedStep. See
 339                 * Intel's 24540640.pdf of June 2003
 340                 */
 341                return SPEEDSTEP_CPU_PIII_T;
 342
 343        case 0x08: /* Intel PIII [Coppermine] */
 344
 345                /* all mobile PIII Coppermines have FSB 100 MHz
 346                 * ==> sort out a few desktop PIIIs. */
 347                rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
 348                dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n",
 349                                msr_lo, msr_hi);
 350                msr_lo &= 0x00c0000;
 351                if (msr_lo != 0x0080000)
 352                        return 0;
 353
 354                /*
 355                 * If the processor is a mobile version,
 356                 * platform ID has bit 50 set
 357                 * it has SpeedStep technology if either
 358                 * bit 56 or 57 is set
 359                 */
 360                rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
 361                dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n",
 362                                msr_lo, msr_hi);
 363                if ((msr_hi & (1<<18)) &&
 364                    (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
 365                        if (c->x86_mask == 0x01) {
 366                                dprintk("early PIII version\n");
 367                                return SPEEDSTEP_CPU_PIII_C_EARLY;
 368                        } else
 369                                return SPEEDSTEP_CPU_PIII_C;
 370                }
 371
 372        default:
 373                return 0;
 374        }
 375}
 376EXPORT_SYMBOL_GPL(speedstep_detect_processor);
 377
 378
 379/*********************************************************************
 380 *                     DETECT SPEEDSTEP SPEEDS                       *
 381 *********************************************************************/
 382
 383unsigned int speedstep_get_freqs(unsigned int processor,
 384                                  unsigned int *low_speed,
 385                                  unsigned int *high_speed,
 386                                  unsigned int *transition_latency,
 387                                  void (*set_state) (unsigned int state))
 388{
 389        unsigned int prev_speed;
 390        unsigned int ret = 0;
 391        unsigned long flags;
 392        struct timeval tv1, tv2;
 393
 394        if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
 395                return -EINVAL;
 396
 397        dprintk("trying to determine both speeds\n");
 398
 399        /* get current speed */
 400        prev_speed = speedstep_get_frequency(processor);
 401        if (!prev_speed)
 402                return -EIO;
 403
 404        dprintk("previous speed is %u\n", prev_speed);
 405
 406        local_irq_save(flags);
 407
 408        /* switch to low state */
 409        set_state(SPEEDSTEP_LOW);
 410        *low_speed = speedstep_get_frequency(processor);
 411        if (!*low_speed) {
 412                ret = -EIO;
 413                goto out;
 414        }
 415
 416        dprintk("low speed is %u\n", *low_speed);
 417
 418        /* start latency measurement */
 419        if (transition_latency)
 420                do_gettimeofday(&tv1);
 421
 422        /* switch to high state */
 423        set_state(SPEEDSTEP_HIGH);
 424
 425        /* end latency measurement */
 426        if (transition_latency)
 427                do_gettimeofday(&tv2);
 428
 429        *high_speed = speedstep_get_frequency(processor);
 430        if (!*high_speed) {
 431                ret = -EIO;
 432                goto out;
 433        }
 434
 435        dprintk("high speed is %u\n", *high_speed);
 436
 437        if (*low_speed == *high_speed) {
 438                ret = -ENODEV;
 439                goto out;
 440        }
 441
 442        /* switch to previous state, if necessary */
 443        if (*high_speed != prev_speed)
 444                set_state(SPEEDSTEP_LOW);
 445
 446        if (transition_latency) {
 447                *transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
 448                        tv2.tv_usec - tv1.tv_usec;
 449                dprintk("transition latency is %u uSec\n", *transition_latency);
 450
 451                /* convert uSec to nSec and add 20% for safety reasons */
 452                *transition_latency *= 1200;
 453
 454                /* check if the latency measurement is too high or too low
 455                 * and set it to a safe value (500uSec) in that case
 456                 */
 457                if (*transition_latency > 10000000 ||
 458                    *transition_latency < 50000) {
 459                        printk(KERN_WARNING PFX "frequency transition "
 460                                        "measured seems out of range (%u "
 461                                        "nSec), falling back to a safe one of"
 462                                        "%u nSec.\n",
 463                                        *transition_latency, 500000);
 464                        *transition_latency = 500000;
 465                }
 466        }
 467
 468out:
 469        local_irq_restore(flags);
 470        return ret;
 471}
 472EXPORT_SYMBOL_GPL(speedstep_get_freqs);
 473
 474#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
 475module_param(relaxed_check, int, 0444);
 476MODULE_PARM_DESC(relaxed_check,
 477                "Don't do all checks for speedstep capability.");
 478#endif
 479
 480MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 481MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
 482MODULE_LICENSE("GPL");
 483