~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to drivers/cpufreq/speedstep-lib.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

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