Commit d77bfa76 authored by Dave Jones's avatar Dave Jones

[CPUFREQ] Make VIA longhaul work on Samuel2 & Ezra again.

These CPUs are actually only longhaul v1 compliant.
This was catastrophic, as the MSRs moved between v1 and v2.
There was also massive confusion in the documentation regarding Ezra.
It's not another variant, so 'v2' never existed.
Renamed v3 (Powersaver) to v2 as a result of this.
parent c2ffde0c
...@@ -5,17 +5,14 @@ ...@@ -5,17 +5,14 @@
* Licensed under the terms of the GNU GPL License version 2. * Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by VIA. * Based upon datasheets & sample CPUs kindly provided by VIA.
* *
* VIA have currently 3 different versions of Longhaul. * VIA have currently 2 different versions of Longhaul.
* * Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
* +---------------------+----------+---------------------------------+ * It is present only in Samuel 1, Samuel 2 and Ezra.
* | Marketing name | Codename | longhaul version / features. | * Version 2 (Powersaver) uses the POWERSAVER MSR at 0x110a.
* +---------------------+----------+---------------------------------+ * It is present in Ezra-T, Nehemiah and above.
* | Samuel/CyrixIII | C5A | v1 : multipliers only | * In addition to scaling multiplier, it can also scale voltage.
* | Samuel2/C3 | C3E/C5B | v1 : multiplier only | * There is provision for scaling FSB too, but this doesn't work
* | Ezra | C5C | v2 : multipliers & voltage | * too well in practice.
* | Ezra-T | C5M | v3 : multipliers, voltage & FSB |
* | Nehemiah | C5N | v3 : multipliers, voltage & FSB |
* +---------------------+----------+---------------------------------+
* *
* BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
*/ */
...@@ -76,7 +73,7 @@ static int longhaul_get_cpu_mult (void) ...@@ -76,7 +73,7 @@ static int longhaul_get_cpu_mult (void)
rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22; invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22;
if (longhaul_version==3) { if (longhaul_version==2) {
if (lo & (1<<27)) if (lo & (1<<27))
invalue+=16; invalue+=16;
} }
...@@ -132,32 +129,15 @@ static void longhaul_setstate (unsigned int clock_ratio_index) ...@@ -132,32 +129,15 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
break; break;
/* /*
* Longhaul v2. (Ezra [C5C]) * Powersaver. (Ezra-T [C5M], Nehemiah [C5N])
* We can scale voltage with this too, but that's currently * We can scale voltage with this too, but that's currently
* disabled until we come up with a decent 'match freq to voltage' * disabled until we come up with a decent 'match freq to voltage'
* algorithm. * algorithm.
* We also need to do the voltage/freq setting in order depending * We also need to do the voltage/freq setting in order depending
* on the direction of scaling (like we do in powernow-k7.c) * on the direction of scaling (like we do in powernow-k7.c)
*/
case 2:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
longhaul.bits.EnableSoftBusRatio = 1;
/* We must program the revision key only with values we
* know about, not blindly copy it from 0:3 */
longhaul.bits.RevisionKey = 1;
wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
__hlt();
break;
/*
* Longhaul v3. (Ezra-T [C5M], Nehemiah [C5N])
* This can also do voltage scaling, but see above.
* Ezra-T was alleged to do FSB scaling too, but it never worked in practice. * Ezra-T was alleged to do FSB scaling too, but it never worked in practice.
*/ */
case 3: case 2:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf; longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
...@@ -235,7 +215,7 @@ static int __init longhaul_get_ranges (void) ...@@ -235,7 +215,7 @@ static int __init longhaul_get_ranges (void)
fsb = eblcr_fsb_table[invalue]; fsb = eblcr_fsb_table[invalue];
break; break;
case 2 ... 3: case 2:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
invalue = longhaul.bits.MaxMHzBR; invalue = longhaul.bits.MaxMHzBR;
...@@ -378,10 +358,10 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -378,10 +358,10 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
break; break;
case 7: /* C5B / C5C */ case 7: /* C5B / C5C */
longhaul_version=1;
switch (c->x86_mask) { switch (c->x86_mask) {
case 0: case 0:
cpuname = "C3 'Samuel 2' [C5B]"; cpuname = "C3 'Samuel 2' [C5B]";
longhaul_version=1;
/* Note, this is not a typo, early Samuel2's had Samuel1 ratios. */ /* Note, this is not a typo, early Samuel2's had Samuel1 ratios. */
memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio)); memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio));
memcpy (eblcr_table, samuel2_eblcr, sizeof(samuel2_eblcr)); memcpy (eblcr_table, samuel2_eblcr, sizeof(samuel2_eblcr));
...@@ -391,7 +371,6 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -391,7 +371,6 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
cpuname = "C3 'Samuel 2' [C5B]"; cpuname = "C3 'Samuel 2' [C5B]";
else else
cpuname = "C3 'Ezra' [C5C]"; cpuname = "C3 'Ezra' [C5C]";
longhaul_version=2;
memcpy (clock_ratio, ezra_clock_ratio, sizeof(ezra_clock_ratio)); memcpy (clock_ratio, ezra_clock_ratio, sizeof(ezra_clock_ratio));
memcpy (eblcr_table, ezra_eblcr, sizeof(ezra_eblcr)); memcpy (eblcr_table, ezra_eblcr, sizeof(ezra_eblcr));
break; break;
...@@ -399,8 +378,8 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -399,8 +378,8 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
break; break;
case 8: case 8:
cpuname = "C3 'Ezra-T [C5M]"; cpuname = "C3 'Ezra-T' [C5M]";
longhaul_version=3; longhaul_version=2;
numscales=32; numscales=32;
memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio)); memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio));
memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr)); memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr));
...@@ -408,7 +387,7 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -408,7 +387,7 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
/* /*
case 9: case 9:
cpuname = "C3 'Nehemiah' [C5N]"; cpuname = "C3 'Nehemiah' [C5N]";
longhaul_version=3; longhaul_version=2;
numscales=32; numscales=32;
memcpy (clock_ratio, nehemiah_clock_ratio, sizeof(nehemiah_clock_ratio)); memcpy (clock_ratio, nehemiah_clock_ratio, sizeof(nehemiah_clock_ratio));
memcpy (eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr)); memcpy (eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr));
...@@ -421,7 +400,7 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -421,7 +400,7 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
printk (KERN_INFO PFX "VIA %s CPU detected. Longhaul v%d supported.\n", printk (KERN_INFO PFX "VIA %s CPU detected. Longhaul v%d supported.\n",
cpuname, longhaul_version); cpuname, longhaul_version);
if ((longhaul_version==2 || longhaul_version==3) && (dont_scale_voltage==0)) if ((longhaul_version==2) && (dont_scale_voltage==0))
longhaul_setup_voltagescaling(); longhaul_setup_voltagescaling();
ret = longhaul_get_ranges(); ret = longhaul_get_ranges();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment