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