Commit 980342a7 authored by Rafa Bilski's avatar Rafa Bilski Committed by Dave Jones

[CPUFREQ] Longhaul - Introduce Nehemiah C

Looks like some time ago I introduced a bug to Longhaul.
I had report that 9x133Mhz CPU is seen as 5x133MHz. So I
changed multipliers table. That was a mistake. According to
documentation table was correct. So only way to avoid 5 or 9
dilema is not use MaxMHzBR for PowerSaver 1.0. One code that
works on all processors. To do it I need also separate flag for
Nehemiah C (min = x4.0) and Nehemiah (min = x5.0).
Signed-off-by: default avatarRafa³ Bilski <rafalbilski@interia.pl>
Signed-off-by: default avatarDave Jones <davej@redhat.com>
parent 58389a86
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#define CPU_EZRA 3 #define CPU_EZRA 3
#define CPU_EZRA_T 4 #define CPU_EZRA_T 4
#define CPU_NEHEMIAH 5 #define CPU_NEHEMIAH 5
#define CPU_NEHEMIAH_C 6
/* Flags */ /* Flags */
#define USE_ACPI_C3 (1 << 1) #define USE_ACPI_C3 (1 << 1)
...@@ -349,67 +350,47 @@ static int guess_fsb(int mult) ...@@ -349,67 +350,47 @@ static int guess_fsb(int mult)
static int __init longhaul_get_ranges(void) static int __init longhaul_get_ranges(void)
{ {
unsigned long invalue;
unsigned int ezra_t_multipliers[32]= {
90, 30, 40, 100, 55, 35, 45, 95,
50, 70, 80, 60, 120, 75, 85, 65,
-1, 110, 120, -1, 135, 115, 125, 105,
130, 150, 160, 140, -1, 155, -1, 145 };
unsigned int j, k = 0; unsigned int j, k = 0;
union msr_longhaul longhaul; int mult;
int mult = 0;
/* Get current frequency */
mult = longhaul_get_cpu_mult();
if (mult == -1) {
printk(KERN_INFO PFX "Invalid (reserved) multiplier!\n");
return -EINVAL;
}
fsb = guess_fsb(mult);
if (fsb == 0) {
printk(KERN_INFO PFX "Invalid (reserved) FSB!\n");
return -EINVAL;
}
/* Get max multiplier - as we always did.
* Longhaul MSR is usefull only when voltage scaling is enabled.
* C3 is booting at max anyway. */
maxmult = mult;
/* Get min multiplier */
switch (longhaul_version) { switch (longhaul_version) {
case TYPE_LONGHAUL_V1: case TYPE_LONGHAUL_V1:
case TYPE_LONGHAUL_V2: case TYPE_LONGHAUL_V2:
/* Ugh, Longhaul v1 didn't have the min/max MSRs.
Assume min=3.0x & max = whatever we booted at. */
minmult = 30; minmult = 30;
maxmult = mult = longhaul_get_cpu_mult();
break; break;
case TYPE_POWERSAVER: case TYPE_POWERSAVER:
/* Ezra-T */ /* Ezra-T */
if (cpu_model==CPU_EZRA_T) { if (cpu_model == CPU_EZRA_T)
minmult = 30; minmult = 30;
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
invalue = longhaul.bits.MaxMHzBR;
if (longhaul.bits.MaxMHzBR4)
invalue += 16;
maxmult = mult = ezra_t_multipliers[invalue];
break;
}
/* Nehemiah */ /* Nehemiah */
if (cpu_model==CPU_NEHEMIAH) { else if (cpu_model == CPU_NEHEMIAH)
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); minmult = 50;
/* Nehemiah C */
/* else if (cpu_model == CPU_NEHEMIAH_C)
* TODO: This code works, but raises a lot of questions. minmult = 40;
* - Some Nehemiah's seem to have broken Min/MaxMHzBR's. break;
* We get around this by using a hardcoded multiplier of 4.0x
* for the minimimum speed, and the speed we booted up at for the max.
* This is done in longhaul_get_cpu_mult() by reading the EBLCR register.
* - According to some VIA documentation EBLCR is only
* in pre-Nehemiah C3s. How this still works is a mystery.
* We're possibly using something undocumented and unsupported,
* But it works, so we don't grumble.
*/
minmult=40;
maxmult = mult = longhaul_get_cpu_mult();
break;
}
} }
fsb = guess_fsb(mult);
dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n", dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n",
minmult/10, minmult%10, maxmult/10, maxmult%10); minmult/10, minmult%10, maxmult/10, maxmult%10);
if (fsb == 0) {
printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
return -EINVAL;
}
highest_speed = calc_speed(maxmult); highest_speed = calc_speed(maxmult);
lowest_speed = calc_speed(minmult); lowest_speed = calc_speed(minmult);
dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb,
...@@ -634,21 +615,23 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) ...@@ -634,21 +615,23 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
break; break;
case 9: case 9:
cpu_model = CPU_NEHEMIAH;
longhaul_version = TYPE_POWERSAVER; longhaul_version = TYPE_POWERSAVER;
numscales=32; numscales=32;
switch (c->x86_mask) { switch (c->x86_mask) {
case 0 ... 1: case 0 ... 1:
cpu_model = CPU_NEHEMIAH;
cpuname = "C3 'Nehemiah A' [C5N]"; cpuname = "C3 'Nehemiah A' [C5N]";
memcpy (clock_ratio, nehemiah_a_clock_ratio, sizeof(nehemiah_a_clock_ratio)); memcpy (clock_ratio, nehemiah_a_clock_ratio, sizeof(nehemiah_a_clock_ratio));
memcpy (eblcr_table, nehemiah_a_eblcr, sizeof(nehemiah_a_eblcr)); memcpy (eblcr_table, nehemiah_a_eblcr, sizeof(nehemiah_a_eblcr));
break; break;
case 2 ... 4: case 2 ... 4:
cpu_model = CPU_NEHEMIAH;
cpuname = "C3 'Nehemiah B' [C5N]"; cpuname = "C3 'Nehemiah B' [C5N]";
memcpy (clock_ratio, nehemiah_b_clock_ratio, sizeof(nehemiah_b_clock_ratio)); memcpy (clock_ratio, nehemiah_b_clock_ratio, sizeof(nehemiah_b_clock_ratio));
memcpy (eblcr_table, nehemiah_b_eblcr, sizeof(nehemiah_b_eblcr)); memcpy (eblcr_table, nehemiah_b_eblcr, sizeof(nehemiah_b_eblcr));
break; break;
case 5 ... 15: case 5 ... 15:
cpu_model = CPU_NEHEMIAH_C;
cpuname = "C3 'Nehemiah C' [C5N]"; cpuname = "C3 'Nehemiah C' [C5N]";
memcpy (clock_ratio, nehemiah_c_clock_ratio, sizeof(nehemiah_c_clock_ratio)); memcpy (clock_ratio, nehemiah_c_clock_ratio, sizeof(nehemiah_c_clock_ratio));
memcpy (eblcr_table, nehemiah_c_eblcr, sizeof(nehemiah_c_eblcr)); memcpy (eblcr_table, nehemiah_c_eblcr, sizeof(nehemiah_c_eblcr));
......
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