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

« back to all changes in this revision

Viewing changes to drivers/cpufreq/longhaul.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) 2001-2004  Dave Jones. <davej@redhat.com>
 
3
 *  (C) 2002  Padraig Brady. <padraig@antefacto.com>
 
4
 *
 
5
 *  Licensed under the terms of the GNU GPL License version 2.
 
6
 *  Based upon datasheets & sample CPUs kindly provided by VIA.
 
7
 *
 
8
 *  VIA have currently 3 different versions of Longhaul.
 
9
 *  Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
 
10
 *   It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0.
 
11
 *  Version 2 of longhaul is backward compatible with v1, but adds
 
12
 *   LONGHAUL MSR for purpose of both frequency and voltage scaling.
 
13
 *   Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C).
 
14
 *  Version 3 of longhaul got renamed to Powersaver and redesigned
 
15
 *   to use only the POWERSAVER MSR at 0x110a.
 
16
 *   It is present in Ezra-T (C5M), Nehemiah (C5X) and above.
 
17
 *   It's pretty much the same feature wise to longhaul v2, though
 
18
 *   there is provision for scaling FSB too, but this doesn't work
 
19
 *   too well in practice so we don't even try to use this.
 
20
 *
 
21
 *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
 
22
 */
 
23
 
 
24
#include <linux/kernel.h>
 
25
#include <linux/module.h>
 
26
#include <linux/moduleparam.h>
 
27
#include <linux/init.h>
 
28
#include <linux/cpufreq.h>
 
29
#include <linux/pci.h>
 
30
#include <linux/slab.h>
 
31
#include <linux/string.h>
 
32
#include <linux/delay.h>
 
33
#include <linux/timex.h>
 
34
#include <linux/io.h>
 
35
#include <linux/acpi.h>
 
36
 
 
37
#include <asm/msr.h>
 
38
#include <acpi/processor.h>
 
39
 
 
40
#include "longhaul.h"
 
41
 
 
42
#define PFX "longhaul: "
 
43
 
 
44
#define TYPE_LONGHAUL_V1        1
 
45
#define TYPE_LONGHAUL_V2        2
 
46
#define TYPE_POWERSAVER         3
 
47
 
 
48
#define CPU_SAMUEL      1
 
49
#define CPU_SAMUEL2     2
 
50
#define CPU_EZRA        3
 
51
#define CPU_EZRA_T      4
 
52
#define CPU_NEHEMIAH    5
 
53
#define CPU_NEHEMIAH_C  6
 
54
 
 
55
/* Flags */
 
56
#define USE_ACPI_C3             (1 << 1)
 
57
#define USE_NORTHBRIDGE         (1 << 2)
 
58
 
 
59
static int cpu_model;
 
60
static unsigned int numscales = 16;
 
61
static unsigned int fsb;
 
62
 
 
63
static const struct mV_pos *vrm_mV_table;
 
64
static const unsigned char *mV_vrm_table;
 
65
 
 
66
static unsigned int highest_speed, lowest_speed; /* kHz */
 
67
static unsigned int minmult, maxmult;
 
68
static int can_scale_voltage;
 
69
static struct acpi_processor *pr;
 
70
static struct acpi_processor_cx *cx;
 
71
static u32 acpi_regs_addr;
 
72
static u8 longhaul_flags;
 
73
static unsigned int longhaul_index;
 
74
 
 
75
/* Module parameters */
 
76
static int scale_voltage;
 
77
static int disable_acpi_c3;
 
78
static int revid_errata;
 
79
 
 
80
 
 
81
/* Clock ratios multiplied by 10 */
 
82
static int mults[32];
 
83
static int eblcr[32];
 
84
static int longhaul_version;
 
85
static struct cpufreq_frequency_table *longhaul_table;
 
86
 
 
87
static char speedbuffer[8];
 
88
 
 
89
static char *print_speed(int speed)
 
90
{
 
91
        if (speed < 1000) {
 
92
                snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed);
 
93
                return speedbuffer;
 
94
        }
 
95
 
 
96
        if (speed%1000 == 0)
 
97
                snprintf(speedbuffer, sizeof(speedbuffer),
 
98
                        "%dGHz", speed/1000);
 
99
        else
 
100
                snprintf(speedbuffer, sizeof(speedbuffer),
 
101
                        "%d.%dGHz", speed/1000, (speed%1000)/100);
 
102
 
 
103
        return speedbuffer;
 
104
}
 
105
 
 
106
 
 
107
static unsigned int calc_speed(int mult)
 
108
{
 
109
        int khz;
 
110
        khz = (mult/10)*fsb;
 
111
        if (mult%10)
 
112
                khz += fsb/2;
 
113
        khz *= 1000;
 
114
        return khz;
 
115
}
 
116
 
 
117
 
 
118
static int longhaul_get_cpu_mult(void)
 
119
{
 
120
        unsigned long invalue = 0, lo, hi;
 
121
 
 
122
        rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
 
123
        invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
 
124
        if (longhaul_version == TYPE_LONGHAUL_V2 ||
 
125
            longhaul_version == TYPE_POWERSAVER) {
 
126
                if (lo & (1<<27))
 
127
                        invalue += 16;
 
128
        }
 
129
        return eblcr[invalue];
 
130
}
 
131
 
 
132
/* For processor with BCR2 MSR */
 
133
 
 
134
static void do_longhaul1(unsigned int mults_index)
 
135
{
 
136
        union msr_bcr2 bcr2;
 
137
 
 
138
        rdmsrl(MSR_VIA_BCR2, bcr2.val);
 
139
        /* Enable software clock multiplier */
 
140
        bcr2.bits.ESOFTBF = 1;
 
141
        bcr2.bits.CLOCKMUL = mults_index & 0xff;
 
142
 
 
143
        /* Sync to timer tick */
 
144
        safe_halt();
 
145
        /* Change frequency on next halt or sleep */
 
146
        wrmsrl(MSR_VIA_BCR2, bcr2.val);
 
147
        /* Invoke transition */
 
148
        ACPI_FLUSH_CPU_CACHE();
 
149
        halt();
 
150
 
 
151
        /* Disable software clock multiplier */
 
152
        local_irq_disable();
 
153
        rdmsrl(MSR_VIA_BCR2, bcr2.val);
 
154
        bcr2.bits.ESOFTBF = 0;
 
155
        wrmsrl(MSR_VIA_BCR2, bcr2.val);
 
156
}
 
157
 
 
158
/* For processor with Longhaul MSR */
 
159
 
 
160
static void do_powersaver(int cx_address, unsigned int mults_index,
 
161
                          unsigned int dir)
 
162
{
 
163
        union msr_longhaul longhaul;
 
164
        u32 t;
 
165
 
 
166
        rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
167
        /* Setup new frequency */
 
168
        if (!revid_errata)
 
169
                longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
 
170
        else
 
171
                longhaul.bits.RevisionKey = 0;
 
172
        longhaul.bits.SoftBusRatio = mults_index & 0xf;
 
173
        longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4;
 
174
        /* Setup new voltage */
 
175
        if (can_scale_voltage)
 
176
                longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f;
 
177
        /* Sync to timer tick */
 
178
        safe_halt();
 
179
        /* Raise voltage if necessary */
 
180
        if (can_scale_voltage && dir) {
 
181
                longhaul.bits.EnableSoftVID = 1;
 
182
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
183
                /* Change voltage */
 
184
                if (!cx_address) {
 
185
                        ACPI_FLUSH_CPU_CACHE();
 
186
                        halt();
 
187
                } else {
 
188
                        ACPI_FLUSH_CPU_CACHE();
 
189
                        /* Invoke C3 */
 
190
                        inb(cx_address);
 
191
                        /* Dummy op - must do something useless after P_LVL3
 
192
                         * read */
 
193
                        t = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
194
                }
 
195
                longhaul.bits.EnableSoftVID = 0;
 
196
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
197
        }
 
198
 
 
199
        /* Change frequency on next halt or sleep */
 
200
        longhaul.bits.EnableSoftBusRatio = 1;
 
201
        wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
202
        if (!cx_address) {
 
203
                ACPI_FLUSH_CPU_CACHE();
 
204
                halt();
 
205
        } else {
 
206
                ACPI_FLUSH_CPU_CACHE();
 
207
                /* Invoke C3 */
 
208
                inb(cx_address);
 
209
                /* Dummy op - must do something useless after P_LVL3 read */
 
210
                t = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
211
        }
 
212
        /* Disable bus ratio bit */
 
213
        longhaul.bits.EnableSoftBusRatio = 0;
 
214
        wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
215
 
 
216
        /* Reduce voltage if necessary */
 
217
        if (can_scale_voltage && !dir) {
 
218
                longhaul.bits.EnableSoftVID = 1;
 
219
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
220
                /* Change voltage */
 
221
                if (!cx_address) {
 
222
                        ACPI_FLUSH_CPU_CACHE();
 
223
                        halt();
 
224
                } else {
 
225
                        ACPI_FLUSH_CPU_CACHE();
 
226
                        /* Invoke C3 */
 
227
                        inb(cx_address);
 
228
                        /* Dummy op - must do something useless after P_LVL3
 
229
                         * read */
 
230
                        t = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
231
                }
 
232
                longhaul.bits.EnableSoftVID = 0;
 
233
                wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
234
        }
 
235
}
 
236
 
 
237
/**
 
238
 * longhaul_set_cpu_frequency()
 
239
 * @mults_index : bitpattern of the new multiplier.
 
240
 *
 
241
 * Sets a new clock ratio.
 
242
 */
 
243
 
 
244
static void longhaul_setstate(unsigned int table_index)
 
245
{
 
246
        unsigned int mults_index;
 
247
        int speed, mult;
 
248
        struct cpufreq_freqs freqs;
 
249
        unsigned long flags;
 
250
        unsigned int pic1_mask, pic2_mask;
 
251
        u16 bm_status = 0;
 
252
        u32 bm_timeout = 1000;
 
253
        unsigned int dir = 0;
 
254
 
 
255
        mults_index = longhaul_table[table_index].index;
 
256
        /* Safety precautions */
 
257
        mult = mults[mults_index & 0x1f];
 
258
        if (mult == -1)
 
259
                return;
 
260
        speed = calc_speed(mult);
 
261
        if ((speed > highest_speed) || (speed < lowest_speed))
 
262
                return;
 
263
        /* Voltage transition before frequency transition? */
 
264
        if (can_scale_voltage && longhaul_index < table_index)
 
265
                dir = 1;
 
266
 
 
267
        freqs.old = calc_speed(longhaul_get_cpu_mult());
 
268
        freqs.new = speed;
 
269
        freqs.cpu = 0; /* longhaul.c is UP only driver */
 
270
 
 
271
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
272
 
 
273
        pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
 
274
                        fsb, mult/10, mult%10, print_speed(speed/1000));
 
275
retry_loop:
 
276
        preempt_disable();
 
277
        local_irq_save(flags);
 
278
 
 
279
        pic2_mask = inb(0xA1);
 
280
        pic1_mask = inb(0x21);  /* works on C3. save mask. */
 
281
        outb(0xFF, 0xA1);       /* Overkill */
 
282
        outb(0xFE, 0x21);       /* TMR0 only */
 
283
 
 
284
        /* Wait while PCI bus is busy. */
 
285
        if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
 
286
            || ((pr != NULL) && pr->flags.bm_control))) {
 
287
                bm_status = inw(acpi_regs_addr);
 
288
                bm_status &= 1 << 4;
 
289
                while (bm_status && bm_timeout) {
 
290
                        outw(1 << 4, acpi_regs_addr);
 
291
                        bm_timeout--;
 
292
                        bm_status = inw(acpi_regs_addr);
 
293
                        bm_status &= 1 << 4;
 
294
                }
 
295
        }
 
296
 
 
297
        if (longhaul_flags & USE_NORTHBRIDGE) {
 
298
                /* Disable AGP and PCI arbiters */
 
299
                outb(3, 0x22);
 
300
        } else if ((pr != NULL) && pr->flags.bm_control) {
 
301
                /* Disable bus master arbitration */
 
302
                acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
 
303
        }
 
304
        switch (longhaul_version) {
 
305
 
 
306
        /*
 
307
         * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B])
 
308
         * Software controlled multipliers only.
 
309
         */
 
310
        case TYPE_LONGHAUL_V1:
 
311
                do_longhaul1(mults_index);
 
312
                break;
 
313
 
 
314
        /*
 
315
         * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5B] and Ezra [C5C]
 
316
         *
 
317
         * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N])
 
318
         * Nehemiah can do FSB scaling too, but this has never been proven
 
319
         * to work in practice.
 
320
         */
 
321
        case TYPE_LONGHAUL_V2:
 
322
        case TYPE_POWERSAVER:
 
323
                if (longhaul_flags & USE_ACPI_C3) {
 
324
                        /* Don't allow wakeup */
 
325
                        acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
 
326
                        do_powersaver(cx->address, mults_index, dir);
 
327
                } else {
 
328
                        do_powersaver(0, mults_index, dir);
 
329
                }
 
330
                break;
 
331
        }
 
332
 
 
333
        if (longhaul_flags & USE_NORTHBRIDGE) {
 
334
                /* Enable arbiters */
 
335
                outb(0, 0x22);
 
336
        } else if ((pr != NULL) && pr->flags.bm_control) {
 
337
                /* Enable bus master arbitration */
 
338
                acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
 
339
        }
 
340
        outb(pic2_mask, 0xA1);  /* restore mask */
 
341
        outb(pic1_mask, 0x21);
 
342
 
 
343
        local_irq_restore(flags);
 
344
        preempt_enable();
 
345
 
 
346
        freqs.new = calc_speed(longhaul_get_cpu_mult());
 
347
        /* Check if requested frequency is set. */
 
348
        if (unlikely(freqs.new != speed)) {
 
349
                printk(KERN_INFO PFX "Failed to set requested frequency!\n");
 
350
                /* Revision ID = 1 but processor is expecting revision key
 
351
                 * equal to 0. Jumpers at the bottom of processor will change
 
352
                 * multiplier and FSB, but will not change bits in Longhaul
 
353
                 * MSR nor enable voltage scaling. */
 
354
                if (!revid_errata) {
 
355
                        printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" "
 
356
                                                "option.\n");
 
357
                        revid_errata = 1;
 
358
                        msleep(200);
 
359
                        goto retry_loop;
 
360
                }
 
361
                /* Why ACPI C3 sometimes doesn't work is a mystery for me.
 
362
                 * But it does happen. Processor is entering ACPI C3 state,
 
363
                 * but it doesn't change frequency. I tried poking various
 
364
                 * bits in northbridge registers, but without success. */
 
365
                if (longhaul_flags & USE_ACPI_C3) {
 
366
                        printk(KERN_INFO PFX "Disabling ACPI C3 support.\n");
 
367
                        longhaul_flags &= ~USE_ACPI_C3;
 
368
                        if (revid_errata) {
 
369
                                printk(KERN_INFO PFX "Disabling \"Ignore "
 
370
                                                "Revision ID\" option.\n");
 
371
                                revid_errata = 0;
 
372
                        }
 
373
                        msleep(200);
 
374
                        goto retry_loop;
 
375
                }
 
376
                /* This shouldn't happen. Longhaul ver. 2 was reported not
 
377
                 * working on processors without voltage scaling, but with
 
378
                 * RevID = 1. RevID errata will make things right. Just
 
379
                 * to be 100% sure. */
 
380
                if (longhaul_version == TYPE_LONGHAUL_V2) {
 
381
                        printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n");
 
382
                        longhaul_version = TYPE_LONGHAUL_V1;
 
383
                        msleep(200);
 
384
                        goto retry_loop;
 
385
                }
 
386
        }
 
387
        /* Report true CPU frequency */
 
388
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
389
 
 
390
        if (!bm_timeout)
 
391
                printk(KERN_INFO PFX "Warning: Timeout while waiting for "
 
392
                                "idle PCI bus.\n");
 
393
}
 
394
 
 
395
/*
 
396
 * Centaur decided to make life a little more tricky.
 
397
 * Only longhaul v1 is allowed to read EBLCR BSEL[0:1].
 
398
 * Samuel2 and above have to try and guess what the FSB is.
 
399
 * We do this by assuming we booted at maximum multiplier, and interpolate
 
400
 * between that value multiplied by possible FSBs and cpu_mhz which
 
401
 * was calculated at boot time. Really ugly, but no other way to do this.
 
402
 */
 
403
 
 
404
#define ROUNDING        0xf
 
405
 
 
406
static int guess_fsb(int mult)
 
407
{
 
408
        int speed = cpu_khz / 1000;
 
409
        int i;
 
410
        int speeds[] = { 666, 1000, 1333, 2000 };
 
411
        int f_max, f_min;
 
412
 
 
413
        for (i = 0; i < 4; i++) {
 
414
                f_max = ((speeds[i] * mult) + 50) / 100;
 
415
                f_max += (ROUNDING / 2);
 
416
                f_min = f_max - ROUNDING;
 
417
                if ((speed <= f_max) && (speed >= f_min))
 
418
                        return speeds[i] / 10;
 
419
        }
 
420
        return 0;
 
421
}
 
422
 
 
423
 
 
424
static int __cpuinit longhaul_get_ranges(void)
 
425
{
 
426
        unsigned int i, j, k = 0;
 
427
        unsigned int ratio;
 
428
        int mult;
 
429
 
 
430
        /* Get current frequency */
 
431
        mult = longhaul_get_cpu_mult();
 
432
        if (mult == -1) {
 
433
                printk(KERN_INFO PFX "Invalid (reserved) multiplier!\n");
 
434
                return -EINVAL;
 
435
        }
 
436
        fsb = guess_fsb(mult);
 
437
        if (fsb == 0) {
 
438
                printk(KERN_INFO PFX "Invalid (reserved) FSB!\n");
 
439
                return -EINVAL;
 
440
        }
 
441
        /* Get max multiplier - as we always did.
 
442
         * Longhaul MSR is useful only when voltage scaling is enabled.
 
443
         * C3 is booting at max anyway. */
 
444
        maxmult = mult;
 
445
        /* Get min multiplier */
 
446
        switch (cpu_model) {
 
447
        case CPU_NEHEMIAH:
 
448
                minmult = 50;
 
449
                break;
 
450
        case CPU_NEHEMIAH_C:
 
451
                minmult = 40;
 
452
                break;
 
453
        default:
 
454
                minmult = 30;
 
455
                break;
 
456
        }
 
457
 
 
458
        pr_debug("MinMult:%d.%dx MaxMult:%d.%dx\n",
 
459
                 minmult/10, minmult%10, maxmult/10, maxmult%10);
 
460
 
 
461
        highest_speed = calc_speed(maxmult);
 
462
        lowest_speed = calc_speed(minmult);
 
463
        pr_debug("FSB:%dMHz  Lowest speed: %s   Highest speed:%s\n", fsb,
 
464
                 print_speed(lowest_speed/1000),
 
465
                 print_speed(highest_speed/1000));
 
466
 
 
467
        if (lowest_speed == highest_speed) {
 
468
                printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n");
 
469
                return -EINVAL;
 
470
        }
 
471
        if (lowest_speed > highest_speed) {
 
472
                printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
 
473
                        lowest_speed, highest_speed);
 
474
                return -EINVAL;
 
475
        }
 
476
 
 
477
        longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
 
478
                        GFP_KERNEL);
 
479
        if (!longhaul_table)
 
480
                return -ENOMEM;
 
481
 
 
482
        for (j = 0; j < numscales; j++) {
 
483
                ratio = mults[j];
 
484
                if (ratio == -1)
 
485
                        continue;
 
486
                if (ratio > maxmult || ratio < minmult)
 
487
                        continue;
 
488
                longhaul_table[k].frequency = calc_speed(ratio);
 
489
                longhaul_table[k].index = j;
 
490
                k++;
 
491
        }
 
492
        if (k <= 1) {
 
493
                kfree(longhaul_table);
 
494
                return -ENODEV;
 
495
        }
 
496
        /* Sort */
 
497
        for (j = 0; j < k - 1; j++) {
 
498
                unsigned int min_f, min_i;
 
499
                min_f = longhaul_table[j].frequency;
 
500
                min_i = j;
 
501
                for (i = j + 1; i < k; i++) {
 
502
                        if (longhaul_table[i].frequency < min_f) {
 
503
                                min_f = longhaul_table[i].frequency;
 
504
                                min_i = i;
 
505
                        }
 
506
                }
 
507
                if (min_i != j) {
 
508
                        swap(longhaul_table[j].frequency,
 
509
                             longhaul_table[min_i].frequency);
 
510
                        swap(longhaul_table[j].index,
 
511
                             longhaul_table[min_i].index);
 
512
                }
 
513
        }
 
514
 
 
515
        longhaul_table[k].frequency = CPUFREQ_TABLE_END;
 
516
 
 
517
        /* Find index we are running on */
 
518
        for (j = 0; j < k; j++) {
 
519
                if (mults[longhaul_table[j].index & 0x1f] == mult) {
 
520
                        longhaul_index = j;
 
521
                        break;
 
522
                }
 
523
        }
 
524
        return 0;
 
525
}
 
526
 
 
527
 
 
528
static void __cpuinit longhaul_setup_voltagescaling(void)
 
529
{
 
530
        union msr_longhaul longhaul;
 
531
        struct mV_pos minvid, maxvid, vid;
 
532
        unsigned int j, speed, pos, kHz_step, numvscales;
 
533
        int min_vid_speed;
 
534
 
 
535
        rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
 
536
        if (!(longhaul.bits.RevisionID & 1)) {
 
537
                printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
 
538
                return;
 
539
        }
 
540
 
 
541
        if (!longhaul.bits.VRMRev) {
 
542
                printk(KERN_INFO PFX "VRM 8.5\n");
 
543
                vrm_mV_table = &vrm85_mV[0];
 
544
                mV_vrm_table = &mV_vrm85[0];
 
545
        } else {
 
546
                printk(KERN_INFO PFX "Mobile VRM\n");
 
547
                if (cpu_model < CPU_NEHEMIAH)
 
548
                        return;
 
549
                vrm_mV_table = &mobilevrm_mV[0];
 
550
                mV_vrm_table = &mV_mobilevrm[0];
 
551
        }
 
552
 
 
553
        minvid = vrm_mV_table[longhaul.bits.MinimumVID];
 
554
        maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
 
555
 
 
556
        if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
 
557
                printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
 
558
                                        "Voltage scaling disabled.\n",
 
559
                                        minvid.mV/1000, minvid.mV%1000,
 
560
                                        maxvid.mV/1000, maxvid.mV%1000);
 
561
                return;
 
562
        }
 
563
 
 
564
        if (minvid.mV == maxvid.mV) {
 
565
                printk(KERN_INFO PFX "Claims to support voltage scaling but "
 
566
                                "min & max are both %d.%03d. "
 
567
                                "Voltage scaling disabled\n",
 
568
                                maxvid.mV/1000, maxvid.mV%1000);
 
569
                return;
 
570
        }
 
571
 
 
572
        /* How many voltage steps*/
 
573
        numvscales = maxvid.pos - minvid.pos + 1;
 
574
        printk(KERN_INFO PFX
 
575
                "Max VID=%d.%03d  "
 
576
                "Min VID=%d.%03d, "
 
577
                "%d possible voltage scales\n",
 
578
                maxvid.mV/1000, maxvid.mV%1000,
 
579
                minvid.mV/1000, minvid.mV%1000,
 
580
                numvscales);
 
581
 
 
582
        /* Calculate max frequency at min voltage */
 
583
        j = longhaul.bits.MinMHzBR;
 
584
        if (longhaul.bits.MinMHzBR4)
 
585
                j += 16;
 
586
        min_vid_speed = eblcr[j];
 
587
        if (min_vid_speed == -1)
 
588
                return;
 
589
        switch (longhaul.bits.MinMHzFSB) {
 
590
        case 0:
 
591
                min_vid_speed *= 13333;
 
592
                break;
 
593
        case 1:
 
594
                min_vid_speed *= 10000;
 
595
                break;
 
596
        case 3:
 
597
                min_vid_speed *= 6666;
 
598
                break;
 
599
        default:
 
600
                return;
 
601
                break;
 
602
        }
 
603
        if (min_vid_speed >= highest_speed)
 
604
                return;
 
605
        /* Calculate kHz for one voltage step */
 
606
        kHz_step = (highest_speed - min_vid_speed) / numvscales;
 
607
 
 
608
        j = 0;
 
609
        while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
 
610
                speed = longhaul_table[j].frequency;
 
611
                if (speed > min_vid_speed)
 
612
                        pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
 
613
                else
 
614
                        pos = minvid.pos;
 
615
                longhaul_table[j].index |= mV_vrm_table[pos] << 8;
 
616
                vid = vrm_mV_table[mV_vrm_table[pos]];
 
617
                printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
 
618
                                speed, j, vid.mV);
 
619
                j++;
 
620
        }
 
621
 
 
622
        can_scale_voltage = 1;
 
623
        printk(KERN_INFO PFX "Voltage scaling enabled.\n");
 
624
}
 
625
 
 
626
 
 
627
static int longhaul_verify(struct cpufreq_policy *policy)
 
628
{
 
629
        return cpufreq_frequency_table_verify(policy, longhaul_table);
 
630
}
 
631
 
 
632
 
 
633
static int longhaul_target(struct cpufreq_policy *policy,
 
634
                            unsigned int target_freq, unsigned int relation)
 
635
{
 
636
        unsigned int table_index = 0;
 
637
        unsigned int i;
 
638
        unsigned int dir = 0;
 
639
        u8 vid, current_vid;
 
640
 
 
641
        if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
 
642
                                relation, &table_index))
 
643
                return -EINVAL;
 
644
 
 
645
        /* Don't set same frequency again */
 
646
        if (longhaul_index == table_index)
 
647
                return 0;
 
648
 
 
649
        if (!can_scale_voltage)
 
650
                longhaul_setstate(table_index);
 
651
        else {
 
652
                /* On test system voltage transitions exceeding single
 
653
                 * step up or down were turning motherboard off. Both
 
654
                 * "ondemand" and "userspace" are unsafe. C7 is doing
 
655
                 * this in hardware, C3 is old and we need to do this
 
656
                 * in software. */
 
657
                i = longhaul_index;
 
658
                current_vid = (longhaul_table[longhaul_index].index >> 8);
 
659
                current_vid &= 0x1f;
 
660
                if (table_index > longhaul_index)
 
661
                        dir = 1;
 
662
                while (i != table_index) {
 
663
                        vid = (longhaul_table[i].index >> 8) & 0x1f;
 
664
                        if (vid != current_vid) {
 
665
                                longhaul_setstate(i);
 
666
                                current_vid = vid;
 
667
                                msleep(200);
 
668
                        }
 
669
                        if (dir)
 
670
                                i++;
 
671
                        else
 
672
                                i--;
 
673
                }
 
674
                longhaul_setstate(table_index);
 
675
        }
 
676
        longhaul_index = table_index;
 
677
        return 0;
 
678
}
 
679
 
 
680
 
 
681
static unsigned int longhaul_get(unsigned int cpu)
 
682
{
 
683
        if (cpu)
 
684
                return 0;
 
685
        return calc_speed(longhaul_get_cpu_mult());
 
686
}
 
687
 
 
688
static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
 
689
                                          u32 nesting_level,
 
690
                                          void *context, void **return_value)
 
691
{
 
692
        struct acpi_device *d;
 
693
 
 
694
        if (acpi_bus_get_device(obj_handle, &d))
 
695
                return 0;
 
696
 
 
697
        *return_value = acpi_driver_data(d);
 
698
        return 1;
 
699
}
 
700
 
 
701
/* VIA don't support PM2 reg, but have something similar */
 
702
static int enable_arbiter_disable(void)
 
703
{
 
704
        struct pci_dev *dev;
 
705
        int status = 1;
 
706
        int reg;
 
707
        u8 pci_cmd;
 
708
 
 
709
        /* Find PLE133 host bridge */
 
710
        reg = 0x78;
 
711
        dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
 
712
                             NULL);
 
713
        /* Find PM133/VT8605 host bridge */
 
714
        if (dev == NULL)
 
715
                dev = pci_get_device(PCI_VENDOR_ID_VIA,
 
716
                                     PCI_DEVICE_ID_VIA_8605_0, NULL);
 
717
        /* Find CLE266 host bridge */
 
718
        if (dev == NULL) {
 
719
                reg = 0x76;
 
720
                dev = pci_get_device(PCI_VENDOR_ID_VIA,
 
721
                                     PCI_DEVICE_ID_VIA_862X_0, NULL);
 
722
                /* Find CN400 V-Link host bridge */
 
723
                if (dev == NULL)
 
724
                        dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL);
 
725
        }
 
726
        if (dev != NULL) {
 
727
                /* Enable access to port 0x22 */
 
728
                pci_read_config_byte(dev, reg, &pci_cmd);
 
729
                if (!(pci_cmd & 1<<7)) {
 
730
                        pci_cmd |= 1<<7;
 
731
                        pci_write_config_byte(dev, reg, pci_cmd);
 
732
                        pci_read_config_byte(dev, reg, &pci_cmd);
 
733
                        if (!(pci_cmd & 1<<7)) {
 
734
                                printk(KERN_ERR PFX
 
735
                                        "Can't enable access to port 0x22.\n");
 
736
                                status = 0;
 
737
                        }
 
738
                }
 
739
                pci_dev_put(dev);
 
740
                return status;
 
741
        }
 
742
        return 0;
 
743
}
 
744
 
 
745
static int longhaul_setup_southbridge(void)
 
746
{
 
747
        struct pci_dev *dev;
 
748
        u8 pci_cmd;
 
749
 
 
750
        /* Find VT8235 southbridge */
 
751
        dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
 
752
        if (dev == NULL)
 
753
                /* Find VT8237 southbridge */
 
754
                dev = pci_get_device(PCI_VENDOR_ID_VIA,
 
755
                                     PCI_DEVICE_ID_VIA_8237, NULL);
 
756
        if (dev != NULL) {
 
757
                /* Set transition time to max */
 
758
                pci_read_config_byte(dev, 0xec, &pci_cmd);
 
759
                pci_cmd &= ~(1 << 2);
 
760
                pci_write_config_byte(dev, 0xec, pci_cmd);
 
761
                pci_read_config_byte(dev, 0xe4, &pci_cmd);
 
762
                pci_cmd &= ~(1 << 7);
 
763
                pci_write_config_byte(dev, 0xe4, pci_cmd);
 
764
                pci_read_config_byte(dev, 0xe5, &pci_cmd);
 
765
                pci_cmd |= 1 << 7;
 
766
                pci_write_config_byte(dev, 0xe5, pci_cmd);
 
767
                /* Get address of ACPI registers block*/
 
768
                pci_read_config_byte(dev, 0x81, &pci_cmd);
 
769
                if (pci_cmd & 1 << 7) {
 
770
                        pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
 
771
                        acpi_regs_addr &= 0xff00;
 
772
                        printk(KERN_INFO PFX "ACPI I/O at 0x%x\n",
 
773
                                        acpi_regs_addr);
 
774
                }
 
775
 
 
776
                pci_dev_put(dev);
 
777
                return 1;
 
778
        }
 
779
        return 0;
 
780
}
 
781
 
 
782
static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy)
 
783
{
 
784
        struct cpuinfo_x86 *c = &cpu_data(0);
 
785
        char *cpuname = NULL;
 
786
        int ret;
 
787
        u32 lo, hi;
 
788
 
 
789
        /* Check what we have on this motherboard */
 
790
        switch (c->x86_model) {
 
791
        case 6:
 
792
                cpu_model = CPU_SAMUEL;
 
793
                cpuname = "C3 'Samuel' [C5A]";
 
794
                longhaul_version = TYPE_LONGHAUL_V1;
 
795
                memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
 
796
                memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr));
 
797
                break;
 
798
 
 
799
        case 7:
 
800
                switch (c->x86_mask) {
 
801
                case 0:
 
802
                        longhaul_version = TYPE_LONGHAUL_V1;
 
803
                        cpu_model = CPU_SAMUEL2;
 
804
                        cpuname = "C3 'Samuel 2' [C5B]";
 
805
                        /* Note, this is not a typo, early Samuel2's had
 
806
                         * Samuel1 ratios. */
 
807
                        memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
 
808
                        memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
 
809
                        break;
 
810
                case 1 ... 15:
 
811
                        longhaul_version = TYPE_LONGHAUL_V2;
 
812
                        if (c->x86_mask < 8) {
 
813
                                cpu_model = CPU_SAMUEL2;
 
814
                                cpuname = "C3 'Samuel 2' [C5B]";
 
815
                        } else {
 
816
                                cpu_model = CPU_EZRA;
 
817
                                cpuname = "C3 'Ezra' [C5C]";
 
818
                        }
 
819
                        memcpy(mults, ezra_mults, sizeof(ezra_mults));
 
820
                        memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr));
 
821
                        break;
 
822
                }
 
823
                break;
 
824
 
 
825
        case 8:
 
826
                cpu_model = CPU_EZRA_T;
 
827
                cpuname = "C3 'Ezra-T' [C5M]";
 
828
                longhaul_version = TYPE_POWERSAVER;
 
829
                numscales = 32;
 
830
                memcpy(mults, ezrat_mults, sizeof(ezrat_mults));
 
831
                memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr));
 
832
                break;
 
833
 
 
834
        case 9:
 
835
                longhaul_version = TYPE_POWERSAVER;
 
836
                numscales = 32;
 
837
                memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
 
838
                memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
 
839
                switch (c->x86_mask) {
 
840
                case 0 ... 1:
 
841
                        cpu_model = CPU_NEHEMIAH;
 
842
                        cpuname = "C3 'Nehemiah A' [C5XLOE]";
 
843
                        break;
 
844
                case 2 ... 4:
 
845
                        cpu_model = CPU_NEHEMIAH;
 
846
                        cpuname = "C3 'Nehemiah B' [C5XLOH]";
 
847
                        break;
 
848
                case 5 ... 15:
 
849
                        cpu_model = CPU_NEHEMIAH_C;
 
850
                        cpuname = "C3 'Nehemiah C' [C5P]";
 
851
                        break;
 
852
                }
 
853
                break;
 
854
 
 
855
        default:
 
856
                cpuname = "Unknown";
 
857
                break;
 
858
        }
 
859
        /* Check Longhaul ver. 2 */
 
860
        if (longhaul_version == TYPE_LONGHAUL_V2) {
 
861
                rdmsr(MSR_VIA_LONGHAUL, lo, hi);
 
862
                if (lo == 0 && hi == 0)
 
863
                        /* Looks like MSR isn't present */
 
864
                        longhaul_version = TYPE_LONGHAUL_V1;
 
865
        }
 
866
 
 
867
        printk(KERN_INFO PFX "VIA %s CPU detected.  ", cpuname);
 
868
        switch (longhaul_version) {
 
869
        case TYPE_LONGHAUL_V1:
 
870
        case TYPE_LONGHAUL_V2:
 
871
                printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version);
 
872
                break;
 
873
        case TYPE_POWERSAVER:
 
874
                printk(KERN_CONT "Powersaver supported.\n");
 
875
                break;
 
876
        };
 
877
 
 
878
        /* Doesn't hurt */
 
879
        longhaul_setup_southbridge();
 
880
 
 
881
        /* Find ACPI data for processor */
 
882
        acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
 
883
                                ACPI_UINT32_MAX, &longhaul_walk_callback, NULL,
 
884
                                NULL, (void *)&pr);
 
885
 
 
886
        /* Check ACPI support for C3 state */
 
887
        if (pr != NULL && longhaul_version == TYPE_POWERSAVER) {
 
888
                cx = &pr->power.states[ACPI_STATE_C3];
 
889
                if (cx->address > 0 && cx->latency <= 1000)
 
890
                        longhaul_flags |= USE_ACPI_C3;
 
891
        }
 
892
        /* Disable if it isn't working */
 
893
        if (disable_acpi_c3)
 
894
                longhaul_flags &= ~USE_ACPI_C3;
 
895
        /* Check if northbridge is friendly */
 
896
        if (enable_arbiter_disable())
 
897
                longhaul_flags |= USE_NORTHBRIDGE;
 
898
 
 
899
        /* Check ACPI support for bus master arbiter disable */
 
900
        if (!(longhaul_flags & USE_ACPI_C3
 
901
             || longhaul_flags & USE_NORTHBRIDGE)
 
902
            && ((pr == NULL) || !(pr->flags.bm_control))) {
 
903
                printk(KERN_ERR PFX
 
904
                        "No ACPI support. Unsupported northbridge.\n");
 
905
                return -ENODEV;
 
906
        }
 
907
 
 
908
        if (longhaul_flags & USE_NORTHBRIDGE)
 
909
                printk(KERN_INFO PFX "Using northbridge support.\n");
 
910
        if (longhaul_flags & USE_ACPI_C3)
 
911
                printk(KERN_INFO PFX "Using ACPI support.\n");
 
912
 
 
913
        ret = longhaul_get_ranges();
 
914
        if (ret != 0)
 
915
                return ret;
 
916
 
 
917
        if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0))
 
918
                longhaul_setup_voltagescaling();
 
919
 
 
920
        policy->cpuinfo.transition_latency = 200000;    /* nsec */
 
921
        policy->cur = calc_speed(longhaul_get_cpu_mult());
 
922
 
 
923
        ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
 
924
        if (ret)
 
925
                return ret;
 
926
 
 
927
        cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu);
 
928
 
 
929
        return 0;
 
930
}
 
931
 
 
932
static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy)
 
933
{
 
934
        cpufreq_frequency_table_put_attr(policy->cpu);
 
935
        return 0;
 
936
}
 
937
 
 
938
static struct freq_attr *longhaul_attr[] = {
 
939
        &cpufreq_freq_attr_scaling_available_freqs,
 
940
        NULL,
 
941
};
 
942
 
 
943
static struct cpufreq_driver longhaul_driver = {
 
944
        .verify = longhaul_verify,
 
945
        .target = longhaul_target,
 
946
        .get    = longhaul_get,
 
947
        .init   = longhaul_cpu_init,
 
948
        .exit   = __devexit_p(longhaul_cpu_exit),
 
949
        .name   = "longhaul",
 
950
        .owner  = THIS_MODULE,
 
951
        .attr   = longhaul_attr,
 
952
};
 
953
 
 
954
 
 
955
static int __init longhaul_init(void)
 
956
{
 
957
        struct cpuinfo_x86 *c = &cpu_data(0);
 
958
 
 
959
        if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
 
960
                return -ENODEV;
 
961
 
 
962
#ifdef CONFIG_SMP
 
963
        if (num_online_cpus() > 1) {
 
964
                printk(KERN_ERR PFX "More than 1 CPU detected, "
 
965
                                "longhaul disabled.\n");
 
966
                return -ENODEV;
 
967
        }
 
968
#endif
 
969
#ifdef CONFIG_X86_IO_APIC
 
970
        if (cpu_has_apic) {
 
971
                printk(KERN_ERR PFX "APIC detected. Longhaul is currently "
 
972
                                "broken in this configuration.\n");
 
973
                return -ENODEV;
 
974
        }
 
975
#endif
 
976
        switch (c->x86_model) {
 
977
        case 6 ... 9:
 
978
                return cpufreq_register_driver(&longhaul_driver);
 
979
        case 10:
 
980
                printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n");
 
981
        default:
 
982
                ;
 
983
        }
 
984
 
 
985
        return -ENODEV;
 
986
}
 
987
 
 
988
 
 
989
static void __exit longhaul_exit(void)
 
990
{
 
991
        int i;
 
992
 
 
993
        for (i = 0; i < numscales; i++) {
 
994
                if (mults[i] == maxmult) {
 
995
                        longhaul_setstate(i);
 
996
                        break;
 
997
                }
 
998
        }
 
999
 
 
1000
        cpufreq_unregister_driver(&longhaul_driver);
 
1001
        kfree(longhaul_table);
 
1002
}
 
1003
 
 
1004
/* Even if BIOS is exporting ACPI C3 state, and it is used
 
1005
 * with success when CPU is idle, this state doesn't
 
1006
 * trigger frequency transition in some cases. */
 
1007
module_param(disable_acpi_c3, int, 0644);
 
1008
MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
 
1009
/* Change CPU voltage with frequency. Very useful to save
 
1010
 * power, but most VIA C3 processors aren't supporting it. */
 
1011
module_param(scale_voltage, int, 0644);
 
1012
MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
 
1013
/* Force revision key to 0 for processors which doesn't
 
1014
 * support voltage scaling, but are introducing itself as
 
1015
 * such. */
 
1016
module_param(revid_errata, int, 0644);
 
1017
MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
 
1018
 
 
1019
MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
 
1020
MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
 
1021
MODULE_LICENSE("GPL");
 
1022
 
 
1023
late_initcall(longhaul_init);
 
1024
module_exit(longhaul_exit);