[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: Rafa Bilski <rafalbilski@interia.pl> Signed-off-by: Dave Jones <davej@redhat.com>
This commit is contained in:
parent
58389a86df
commit
980342a7eb
1 changed files with 28 additions and 45 deletions
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
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));
|
||||||
|
|
Loading…
Reference in a new issue