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