Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
0004  *
0005  *  Library for common functions for Intel SpeedStep v.1 and v.2 support
0006  *
0007  *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
0008  */
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/moduleparam.h>
0015 #include <linux/init.h>
0016 #include <linux/cpufreq.h>
0017 
0018 #include <asm/msr.h>
0019 #include <asm/tsc.h>
0020 #include "speedstep-lib.h"
0021 
0022 #define PFX "speedstep-lib: "
0023 
0024 #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
0025 static int relaxed_check;
0026 #else
0027 #define relaxed_check 0
0028 #endif
0029 
0030 /*********************************************************************
0031  *                   GET PROCESSOR CORE SPEED IN KHZ                 *
0032  *********************************************************************/
0033 
0034 static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
0035 {
0036     /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
0037     static const struct {
0038         unsigned int ratio; /* Frequency Multiplier (x10) */
0039         u8 bitmap;      /* power on configuration bits
0040                     [27, 25:22] (in MSR 0x2a) */
0041     } msr_decode_mult[] = {
0042         { 30, 0x01 },
0043         { 35, 0x05 },
0044         { 40, 0x02 },
0045         { 45, 0x06 },
0046         { 50, 0x00 },
0047         { 55, 0x04 },
0048         { 60, 0x0b },
0049         { 65, 0x0f },
0050         { 70, 0x09 },
0051         { 75, 0x0d },
0052         { 80, 0x0a },
0053         { 85, 0x26 },
0054         { 90, 0x20 },
0055         { 100, 0x2b },
0056         { 0, 0xff } /* error or unknown value */
0057     };
0058 
0059     /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
0060     static const struct {
0061         unsigned int value; /* Front Side Bus speed in MHz */
0062         u8 bitmap;      /* power on configuration bits [18: 19]
0063                     (in MSR 0x2a) */
0064     } msr_decode_fsb[] = {
0065         {  66, 0x0 },
0066         { 100, 0x2 },
0067         { 133, 0x1 },
0068         {   0, 0xff}
0069     };
0070 
0071     u32 msr_lo, msr_tmp;
0072     int i = 0, j = 0;
0073 
0074     /* read MSR 0x2a - we only need the low 32 bits */
0075     rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
0076     pr_debug("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
0077     msr_tmp = msr_lo;
0078 
0079     /* decode the FSB */
0080     msr_tmp &= 0x00c0000;
0081     msr_tmp >>= 18;
0082     while (msr_tmp != msr_decode_fsb[i].bitmap) {
0083         if (msr_decode_fsb[i].bitmap == 0xff)
0084             return 0;
0085         i++;
0086     }
0087 
0088     /* decode the multiplier */
0089     if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) {
0090         pr_debug("workaround for early PIIIs\n");
0091         msr_lo &= 0x03c00000;
0092     } else
0093         msr_lo &= 0x0bc00000;
0094     msr_lo >>= 22;
0095     while (msr_lo != msr_decode_mult[j].bitmap) {
0096         if (msr_decode_mult[j].bitmap == 0xff)
0097             return 0;
0098         j++;
0099     }
0100 
0101     pr_debug("speed is %u\n",
0102         (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
0103 
0104     return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100;
0105 }
0106 
0107 
0108 static unsigned int pentiumM_get_frequency(void)
0109 {
0110     u32 msr_lo, msr_tmp;
0111 
0112     rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
0113     pr_debug("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
0114 
0115     /* see table B-2 of 24547212.pdf */
0116     if (msr_lo & 0x00040000) {
0117         printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n",
0118                 msr_lo, msr_tmp);
0119         return 0;
0120     }
0121 
0122     msr_tmp = (msr_lo >> 22) & 0x1f;
0123     pr_debug("bits 22-26 are 0x%x, speed is %u\n",
0124             msr_tmp, (msr_tmp * 100 * 1000));
0125 
0126     return msr_tmp * 100 * 1000;
0127 }
0128 
0129 static unsigned int pentium_core_get_frequency(void)
0130 {
0131     u32 fsb = 0;
0132     u32 msr_lo, msr_tmp;
0133     int ret;
0134 
0135     rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
0136     /* see table B-2 of 25366920.pdf */
0137     switch (msr_lo & 0x07) {
0138     case 5:
0139         fsb = 100000;
0140         break;
0141     case 1:
0142         fsb = 133333;
0143         break;
0144     case 3:
0145         fsb = 166667;
0146         break;
0147     case 2:
0148         fsb = 200000;
0149         break;
0150     case 0:
0151         fsb = 266667;
0152         break;
0153     case 4:
0154         fsb = 333333;
0155         break;
0156     default:
0157         pr_err("PCORE - MSR_FSB_FREQ undefined value\n");
0158     }
0159 
0160     rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
0161     pr_debug("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n",
0162             msr_lo, msr_tmp);
0163 
0164     msr_tmp = (msr_lo >> 22) & 0x1f;
0165     pr_debug("bits 22-26 are 0x%x, speed is %u\n",
0166             msr_tmp, (msr_tmp * fsb));
0167 
0168     ret = (msr_tmp * fsb);
0169     return ret;
0170 }
0171 
0172 
0173 static unsigned int pentium4_get_frequency(void)
0174 {
0175     struct cpuinfo_x86 *c = &boot_cpu_data;
0176     u32 msr_lo, msr_hi, mult;
0177     unsigned int fsb = 0;
0178     unsigned int ret;
0179     u8 fsb_code;
0180 
0181     /* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency
0182      * to System Bus Frequency Ratio Field in the Processor Frequency
0183      * Configuration Register of the MSR. Therefore the current
0184      * frequency cannot be calculated and has to be measured.
0185      */
0186     if (c->x86_model < 2)
0187         return cpu_khz;
0188 
0189     rdmsr(0x2c, msr_lo, msr_hi);
0190 
0191     pr_debug("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);
0192 
0193     /* decode the FSB: see IA-32 Intel (C) Architecture Software
0194      * Developer's Manual, Volume 3: System Prgramming Guide,
0195      * revision #12 in Table B-1: MSRs in the Pentium 4 and
0196      * Intel Xeon Processors, on page B-4 and B-5.
0197      */
0198     fsb_code = (msr_lo >> 16) & 0x7;
0199     switch (fsb_code) {
0200     case 0:
0201         fsb = 100 * 1000;
0202         break;
0203     case 1:
0204         fsb = 13333 * 10;
0205         break;
0206     case 2:
0207         fsb = 200 * 1000;
0208         break;
0209     }
0210 
0211     if (!fsb)
0212         printk(KERN_DEBUG PFX "couldn't detect FSB speed. "
0213                 "Please send an e-mail to <linux@brodo.de>\n");
0214 
0215     /* Multiplier. */
0216     mult = msr_lo >> 24;
0217 
0218     pr_debug("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n",
0219             fsb, mult, (fsb * mult));
0220 
0221     ret = (fsb * mult);
0222     return ret;
0223 }
0224 
0225 
0226 /* Warning: may get called from smp_call_function_single. */
0227 unsigned int speedstep_get_frequency(enum speedstep_processor processor)
0228 {
0229     switch (processor) {
0230     case SPEEDSTEP_CPU_PCORE:
0231         return pentium_core_get_frequency();
0232     case SPEEDSTEP_CPU_PM:
0233         return pentiumM_get_frequency();
0234     case SPEEDSTEP_CPU_P4D:
0235     case SPEEDSTEP_CPU_P4M:
0236         return pentium4_get_frequency();
0237     case SPEEDSTEP_CPU_PIII_T:
0238     case SPEEDSTEP_CPU_PIII_C:
0239     case SPEEDSTEP_CPU_PIII_C_EARLY:
0240         return pentium3_get_frequency(processor);
0241     default:
0242         return 0;
0243     }
0244     return 0;
0245 }
0246 EXPORT_SYMBOL_GPL(speedstep_get_frequency);
0247 
0248 
0249 /*********************************************************************
0250  *                 DETECT SPEEDSTEP-CAPABLE PROCESSOR                *
0251  *********************************************************************/
0252 
0253 /* Keep in sync with the x86_cpu_id tables in the different modules */
0254 enum speedstep_processor speedstep_detect_processor(void)
0255 {
0256     struct cpuinfo_x86 *c = &cpu_data(0);
0257     u32 ebx, msr_lo, msr_hi;
0258 
0259     pr_debug("x86: %x, model: %x\n", c->x86, c->x86_model);
0260 
0261     if ((c->x86_vendor != X86_VENDOR_INTEL) ||
0262         ((c->x86 != 6) && (c->x86 != 0xF)))
0263         return 0;
0264 
0265     if (c->x86 == 0xF) {
0266         /* Intel Mobile Pentium 4-M
0267          * or Intel Mobile Pentium 4 with 533 MHz FSB */
0268         if (c->x86_model != 2)
0269             return 0;
0270 
0271         ebx = cpuid_ebx(0x00000001);
0272         ebx &= 0x000000FF;
0273 
0274         pr_debug("ebx value is %x, x86_stepping is %x\n", ebx, c->x86_stepping);
0275 
0276         switch (c->x86_stepping) {
0277         case 4:
0278             /*
0279              * B-stepping [M-P4-M]
0280              * sample has ebx = 0x0f, production has 0x0e.
0281              */
0282             if ((ebx == 0x0e) || (ebx == 0x0f))
0283                 return SPEEDSTEP_CPU_P4M;
0284             break;
0285         case 7:
0286             /*
0287              * C-stepping [M-P4-M]
0288              * needs to have ebx=0x0e, else it's a celeron:
0289              * cf. 25130917.pdf / page 7, footnote 5 even
0290              * though 25072120.pdf / page 7 doesn't say
0291              * samples are only of B-stepping...
0292              */
0293             if (ebx == 0x0e)
0294                 return SPEEDSTEP_CPU_P4M;
0295             break;
0296         case 9:
0297             /*
0298              * D-stepping [M-P4-M or M-P4/533]
0299              *
0300              * this is totally strange: CPUID 0x0F29 is
0301              * used by M-P4-M, M-P4/533 and(!) Celeron CPUs.
0302              * The latter need to be sorted out as they don't
0303              * support speedstep.
0304              * Celerons with CPUID 0x0F29 may have either
0305              * ebx=0x8 or 0xf -- 25130917.pdf doesn't say anything
0306              * specific.
0307              * M-P4-Ms may have either ebx=0xe or 0xf [see above]
0308              * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
0309              * also, M-P4M HTs have ebx=0x8, too
0310              * For now, they are distinguished by the model_id
0311              * string
0312              */
0313             if ((ebx == 0x0e) ||
0314                 (strstr(c->x86_model_id,
0315                     "Mobile Intel(R) Pentium(R) 4") != NULL))
0316                 return SPEEDSTEP_CPU_P4M;
0317             break;
0318         default:
0319             break;
0320         }
0321         return 0;
0322     }
0323 
0324     switch (c->x86_model) {
0325     case 0x0B: /* Intel PIII [Tualatin] */
0326         /* cpuid_ebx(1) is 0x04 for desktop PIII,
0327          * 0x06 for mobile PIII-M */
0328         ebx = cpuid_ebx(0x00000001);
0329         pr_debug("ebx is %x\n", ebx);
0330 
0331         ebx &= 0x000000FF;
0332 
0333         if (ebx != 0x06)
0334             return 0;
0335 
0336         /* So far all PIII-M processors support SpeedStep. See
0337          * Intel's 24540640.pdf of June 2003
0338          */
0339         return SPEEDSTEP_CPU_PIII_T;
0340 
0341     case 0x08: /* Intel PIII [Coppermine] */
0342 
0343         /* all mobile PIII Coppermines have FSB 100 MHz
0344          * ==> sort out a few desktop PIIIs. */
0345         rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
0346         pr_debug("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n",
0347                 msr_lo, msr_hi);
0348         msr_lo &= 0x00c0000;
0349         if (msr_lo != 0x0080000)
0350             return 0;
0351 
0352         /*
0353          * If the processor is a mobile version,
0354          * platform ID has bit 50 set
0355          * it has SpeedStep technology if either
0356          * bit 56 or 57 is set
0357          */
0358         rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
0359         pr_debug("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n",
0360                 msr_lo, msr_hi);
0361         if ((msr_hi & (1<<18)) &&
0362             (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
0363             if (c->x86_stepping == 0x01) {
0364                 pr_debug("early PIII version\n");
0365                 return SPEEDSTEP_CPU_PIII_C_EARLY;
0366             } else
0367                 return SPEEDSTEP_CPU_PIII_C;
0368         }
0369         fallthrough;
0370     default:
0371         return 0;
0372     }
0373 }
0374 EXPORT_SYMBOL_GPL(speedstep_detect_processor);
0375 
0376 
0377 /*********************************************************************
0378  *                     DETECT SPEEDSTEP SPEEDS                       *
0379  *********************************************************************/
0380 
0381 unsigned int speedstep_get_freqs(enum speedstep_processor processor,
0382                   unsigned int *low_speed,
0383                   unsigned int *high_speed,
0384                   unsigned int *transition_latency,
0385                   void (*set_state) (unsigned int state))
0386 {
0387     unsigned int prev_speed;
0388     unsigned int ret = 0;
0389     unsigned long flags;
0390     ktime_t tv1, tv2;
0391 
0392     if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
0393         return -EINVAL;
0394 
0395     pr_debug("trying to determine both speeds\n");
0396 
0397     /* get current speed */
0398     prev_speed = speedstep_get_frequency(processor);
0399     if (!prev_speed)
0400         return -EIO;
0401 
0402     pr_debug("previous speed is %u\n", prev_speed);
0403 
0404     preempt_disable();
0405     local_irq_save(flags);
0406 
0407     /* switch to low state */
0408     set_state(SPEEDSTEP_LOW);
0409     *low_speed = speedstep_get_frequency(processor);
0410     if (!*low_speed) {
0411         ret = -EIO;
0412         goto out;
0413     }
0414 
0415     pr_debug("low speed is %u\n", *low_speed);
0416 
0417     /* start latency measurement */
0418     if (transition_latency)
0419         tv1 = ktime_get();
0420 
0421     /* switch to high state */
0422     set_state(SPEEDSTEP_HIGH);
0423 
0424     /* end latency measurement */
0425     if (transition_latency)
0426         tv2 = ktime_get();
0427 
0428     *high_speed = speedstep_get_frequency(processor);
0429     if (!*high_speed) {
0430         ret = -EIO;
0431         goto out;
0432     }
0433 
0434     pr_debug("high speed is %u\n", *high_speed);
0435 
0436     if (*low_speed == *high_speed) {
0437         ret = -ENODEV;
0438         goto out;
0439     }
0440 
0441     /* switch to previous state, if necessary */
0442     if (*high_speed != prev_speed)
0443         set_state(SPEEDSTEP_LOW);
0444 
0445     if (transition_latency) {
0446         *transition_latency = ktime_to_us(ktime_sub(tv2, tv1));
0447         pr_debug("transition latency is %u uSec\n", *transition_latency);
0448 
0449         /* convert uSec to nSec and add 20% for safety reasons */
0450         *transition_latency *= 1200;
0451 
0452         /* check if the latency measurement is too high or too low
0453          * and set it to a safe value (500uSec) in that case
0454          */
0455         if (*transition_latency > 10000000 ||
0456             *transition_latency < 50000) {
0457             pr_warn("frequency transition measured seems out of range (%u nSec), falling back to a safe one of %u nSec\n",
0458                 *transition_latency, 500000);
0459             *transition_latency = 500000;
0460         }
0461     }
0462 
0463 out:
0464     local_irq_restore(flags);
0465     preempt_enable();
0466 
0467     return ret;
0468 }
0469 EXPORT_SYMBOL_GPL(speedstep_get_freqs);
0470 
0471 #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
0472 module_param(relaxed_check, int, 0444);
0473 MODULE_PARM_DESC(relaxed_check,
0474         "Don't do all checks for speedstep capability.");
0475 #endif
0476 
0477 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
0478 MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
0479 MODULE_LICENSE("GPL");