Commit 84179c9b authored by Dave Jones's avatar Dave Jones

Merge wopr.codemonkey.org.uk:/mnt/nfs/sepia/bar/src/kernel/2.6/trees/bk-linus

into wopr.codemonkey.org.uk:/mnt/nfs/sepia/bar/src/kernel/2.6/trees/cpufreq
parents ebf7c862 180ca8dd
...@@ -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*
*/ */
...@@ -66,7 +63,11 @@ static struct cpufreq_frequency_table *longhaul_table; ...@@ -66,7 +63,11 @@ static struct cpufreq_frequency_table *longhaul_table;
static unsigned int calc_speed (int mult, int fsb) static unsigned int calc_speed (int mult, int fsb)
{ {
return ((mult/10)*fsb) + ((mult%10)*(fsb/2)); int mhz;
mhz = (mult/10)*fsb;
if (mult%10)
mhz += fsb/2;
return mhz;
} }
...@@ -76,7 +77,7 @@ static int longhaul_get_cpu_mult (void) ...@@ -76,7 +77,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 +133,15 @@ static void longhaul_setstate (unsigned int clock_ratio_index) ...@@ -132,32 +133,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;
...@@ -214,6 +198,7 @@ static int guess_fsb(int maxmult) ...@@ -214,6 +198,7 @@ static int guess_fsb(int maxmult)
static int __init longhaul_get_ranges (void) static int __init longhaul_get_ranges (void)
{ {
struct cpuinfo_x86 *c = cpu_data;
unsigned long invalue; unsigned long invalue;
unsigned int minmult=0, maxmult=0; unsigned int minmult=0, maxmult=0;
unsigned int multipliers[32]= { unsigned int multipliers[32]= {
...@@ -232,10 +217,13 @@ static int __init longhaul_get_ranges (void) ...@@ -232,10 +217,13 @@ static int __init longhaul_get_ranges (void)
maxmult = longhaul_get_cpu_mult(); maxmult = longhaul_get_cpu_mult();
rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
invalue = (lo & (1<<18|1<<19)) >>18; invalue = (lo & (1<<18|1<<19)) >>18;
fsb = eblcr_fsb_table[invalue]; if (c->x86_model==6)
fsb = eblcr_fsb_table[invalue];
else
fsb = guess_fsb(maxmult);
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 +366,10 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -378,10 +366,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 +379,6 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -391,7 +379,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,20 +386,21 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -399,20 +386,21 @@ 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));
break; break;
/*
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));
*/ break;
default: default:
cpuname = "Unknown"; cpuname = "Unknown";
break; break;
...@@ -421,7 +409,7 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -421,7 +409,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