aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index fa5cac255c16..b59878a0d9b3 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -8,12 +8,11 @@
8 * VIA have currently 3 different versions of Longhaul. 8 * VIA have currently 3 different versions of Longhaul.
9 * Version 1 (Longhaul) uses the BCR2 MSR at 0x1147. 9 * Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
10 * It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0. 10 * It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0.
11 * Version 2 of longhaul is the same as v1, but adds voltage scaling. 11 * Version 2 of longhaul is backward compatible with v1, but adds
12 * Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C) 12 * LONGHAUL MSR for purpose of both frequency and voltage scaling.
13 * voltage scaling support has currently been disabled in this driver 13 * Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C).
14 * until we have code that gets it right.
15 * Version 3 of longhaul got renamed to Powersaver and redesigned 14 * Version 3 of longhaul got renamed to Powersaver and redesigned
16 * to use the POWERSAVER MSR at 0x110a. 15 * to use only the POWERSAVER MSR at 0x110a.
17 * It is present in Ezra-T (C5M), Nehemiah (C5X) and above. 16 * It is present in Ezra-T (C5M), Nehemiah (C5X) and above.
18 * It's pretty much the same feature wise to longhaul v2, though 17 * It's pretty much the same feature wise to longhaul v2, though
19 * there is provision for scaling FSB too, but this doesn't work 18 * there is provision for scaling FSB too, but this doesn't work
@@ -298,26 +297,19 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
298 /* 297 /*
299 * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B]) 298 * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B])
300 * Software controlled multipliers only. 299 * Software controlled multipliers only.
301 *
302 * *NB* Until we get voltage scaling working v1 & v2 are the same code.
303 * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5b] and Ezra [C5C]
304 */ 300 */
305 case TYPE_LONGHAUL_V1: 301 case TYPE_LONGHAUL_V1:
306 case TYPE_LONGHAUL_V2:
307 do_longhaul1(clock_ratio_index); 302 do_longhaul1(clock_ratio_index);
308 break; 303 break;
309 304
310 /* 305 /*
306 * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5B] and Ezra [C5C]
307 *
311 * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N]) 308 * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N])
312 * We can scale voltage with this too, but that's currently
313 * disabled until we come up with a decent 'match freq to voltage'
314 * algorithm.
315 * When we add voltage scaling, we will also need to do the
316 * voltage/freq setting in order depending on the direction
317 * of scaling (like we do in powernow-k7.c)
318 * Nehemiah can do FSB scaling too, but this has never been proven 309 * Nehemiah can do FSB scaling too, but this has never been proven
319 * to work in practice. 310 * to work in practice.
320 */ 311 */
312 case TYPE_LONGHAUL_V2:
321 case TYPE_POWERSAVER: 313 case TYPE_POWERSAVER:
322 if (longhaul_flags & USE_ACPI_C3) { 314 if (longhaul_flags & USE_ACPI_C3) {
323 /* Don't allow wakeup */ 315 /* Don't allow wakeup */
@@ -342,6 +334,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
342 local_irq_restore(flags); 334 local_irq_restore(flags);
343 preempt_enable(); 335 preempt_enable();
344 336
337 freqs.new = calc_speed(longhaul_get_cpu_mult());
345 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 338 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
346} 339}
347 340
@@ -471,6 +464,8 @@ static void __init longhaul_setup_voltagescaling(void)
471 mV_vrm_table = &mV_vrm85[0]; 464 mV_vrm_table = &mV_vrm85[0];
472 } else { 465 } else {
473 printk (KERN_INFO PFX "Mobile VRM\n"); 466 printk (KERN_INFO PFX "Mobile VRM\n");
467 if (cpu_model < CPU_NEHEMIAH)
468 return;
474 vrm_mV_table = &mobilevrm_mV[0]; 469 vrm_mV_table = &mobilevrm_mV[0];
475 mV_vrm_table = &mV_mobilevrm[0]; 470 mV_vrm_table = &mV_mobilevrm[0];
476 } 471 }
@@ -656,6 +651,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
656 struct cpuinfo_x86 *c = cpu_data; 651 struct cpuinfo_x86 *c = cpu_data;
657 char *cpuname=NULL; 652 char *cpuname=NULL;
658 int ret; 653 int ret;
654 u32 lo, hi;
659 int vt8235_present; 655 int vt8235_present;
660 656
661 /* Check what we have on this motherboard */ 657 /* Check what we have on this motherboard */
@@ -669,16 +665,20 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
669 break; 665 break;
670 666
671 case 7: 667 case 7:
672 longhaul_version = TYPE_LONGHAUL_V1;
673 switch (c->x86_mask) { 668 switch (c->x86_mask) {
674 case 0: 669 case 0:
670 longhaul_version = TYPE_LONGHAUL_V1;
675 cpu_model = CPU_SAMUEL2; 671 cpu_model = CPU_SAMUEL2;
676 cpuname = "C3 'Samuel 2' [C5B]"; 672 cpuname = "C3 'Samuel 2' [C5B]";
677 /* Note, this is not a typo, early Samuel2's had Samuel1 ratios. */ 673 /* Note, this is not a typo, early Samuel2's had
678 memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio)); 674 * Samuel1 ratios. */
679 memcpy (eblcr_table, samuel2_eblcr, sizeof(samuel2_eblcr)); 675 memcpy(clock_ratio, samuel1_clock_ratio,
676 sizeof(samuel1_clock_ratio));
677 memcpy(eblcr_table, samuel2_eblcr,
678 sizeof(samuel2_eblcr));
680 break; 679 break;
681 case 1 ... 15: 680 case 1 ... 15:
681 longhaul_version = TYPE_LONGHAUL_V2;
682 if (c->x86_mask < 8) { 682 if (c->x86_mask < 8) {
683 cpu_model = CPU_SAMUEL2; 683 cpu_model = CPU_SAMUEL2;
684 cpuname = "C3 'Samuel 2' [C5B]"; 684 cpuname = "C3 'Samuel 2' [C5B]";
@@ -686,8 +686,10 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
686 cpu_model = CPU_EZRA; 686 cpu_model = CPU_EZRA;
687 cpuname = "C3 'Ezra' [C5C]"; 687 cpuname = "C3 'Ezra' [C5C]";
688 } 688 }
689 memcpy (clock_ratio, ezra_clock_ratio, sizeof(ezra_clock_ratio)); 689 memcpy(clock_ratio, ezra_clock_ratio,
690 memcpy (eblcr_table, ezra_eblcr, sizeof(ezra_eblcr)); 690 sizeof(ezra_clock_ratio));
691 memcpy(eblcr_table, ezra_eblcr,
692 sizeof(ezra_eblcr));
691 break; 693 break;
692 } 694 }
693 break; 695 break;
@@ -728,6 +730,13 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
728 cpuname = "Unknown"; 730 cpuname = "Unknown";
729 break; 731 break;
730 } 732 }
733 /* Check Longhaul ver. 2 */
734 if (longhaul_version == TYPE_LONGHAUL_V2) {
735 rdmsr(MSR_VIA_LONGHAUL, lo, hi);
736 if (lo == 0 && hi == 0)
737 /* Looks like MSR isn't present */
738 longhaul_version = TYPE_LONGHAUL_V1;
739 }
731 740
732 printk (KERN_INFO PFX "VIA %s CPU detected. ", cpuname); 741 printk (KERN_INFO PFX "VIA %s CPU detected. ", cpuname);
733 switch (longhaul_version) { 742 switch (longhaul_version) {
@@ -749,7 +758,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
749 NULL, (void *)&pr); 758 NULL, (void *)&pr);
750 759
751 /* Check ACPI support for C3 state */ 760 /* Check ACPI support for C3 state */
752 if (pr != NULL && longhaul_version == TYPE_POWERSAVER) { 761 if (pr != NULL && longhaul_version != TYPE_LONGHAUL_V1) {
753 cx = &pr->power.states[ACPI_STATE_C3]; 762 cx = &pr->power.states[ACPI_STATE_C3];
754 if (cx->address > 0 && cx->latency <= 1000) { 763 if (cx->address > 0 && cx->latency <= 1000) {
755 longhaul_flags |= USE_ACPI_C3; 764 longhaul_flags |= USE_ACPI_C3;