aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/cpu
diff options
context:
space:
mode:
authorRafał Bilski <rafalbilski@interia.pl>2007-02-14 16:00:37 -0500
committerDave Jones <davej@redhat.com>2007-02-14 17:32:06 -0500
commit2b8c0e13026c30bd154dc521ffc235360830c712 (patch)
treecdf66598cd4cbb69587a7e1f5601a78c6c2db6f4 /arch/i386/kernel/cpu
parentb6f45a4b071d77777d70e097d429273aeedff717 (diff)
[CPUFREQ] Longhaul - Redo Longhaul ver. 2
Start using v2 version of Longhaul when available. It provides voltage scaling and can use ACPI C3 state. That's curious. CPU will not change frequency on ACPI C3 when v1 is in use, but it will when v2 is used. Driver will return max frequency all the time if this isn't true for all processors. There is strange thing with mobile voltage. Looks like only Nehemiah (C3-M) supports it. Earlier processors have different mobile VRM (in docs), but I can't find any which is using it. Looks like all are using VRM 8.5. So fail for non Nehemiah with mobile VRM. Signed-off-by: Rafal Bilski <rafalbilski@interia.pl> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'arch/i386/kernel/cpu')
-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;