Commit 6ded2df9 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[CPUFREQ] Nehemiah improvements for longhaul driver.

From Andreas Meisinger 
parent a7615aeb
...@@ -82,6 +82,10 @@ static int longhaul_get_cpu_mult (void) ...@@ -82,6 +82,10 @@ static int longhaul_get_cpu_mult (void)
if (lo & (1<<27)) if (lo & (1<<27))
invalue+=16; invalue+=16;
} }
if (longhaul_version==4) {
if (lo & (1<<27))
invalue+=16;
}
return eblcr_table[invalue]; return eblcr_table[invalue];
} }
...@@ -158,6 +162,22 @@ static void longhaul_setstate (unsigned int clock_ratio_index) ...@@ -158,6 +162,22 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
longhaul.bits.RevisionKey = 3; longhaul.bits.RevisionKey = 3;
wrmsrl (MSR_VIA_LONGHAUL, longhaul.val); wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
break; break;
case 4:
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;
longhaul.bits.RevisionKey = 0x0;
wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
__hlt();
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
longhaul.bits.EnableSoftBusRatio = 0;
longhaul.bits.RevisionKey = 0xf;
wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
break;
} }
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
...@@ -207,7 +227,7 @@ static int guess_fsb(int maxmult) ...@@ -207,7 +227,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; struct cpuinfo_x86 *c = cpu_data;
unsigned long invalue; unsigned long invalue,invalue2;
unsigned int minmult=0, maxmult=0; unsigned int minmult=0, maxmult=0;
unsigned int multipliers[32]= { unsigned int multipliers[32]= {
50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65, 50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
...@@ -234,8 +254,6 @@ static int __init longhaul_get_ranges (void) ...@@ -234,8 +254,6 @@ static int __init longhaul_get_ranges (void)
case 2: case 2:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
//TODO: Nehemiah may have borken MaxMHzBR.
// need to extrapolate from FSB.
invalue = longhaul.bits.MaxMHzBR; invalue = longhaul.bits.MaxMHzBR;
if (longhaul.bits.MaxMHzBR4) if (longhaul.bits.MaxMHzBR4)
invalue += 16; invalue += 16;
...@@ -258,6 +276,38 @@ static int __init longhaul_get_ranges (void) ...@@ -258,6 +276,38 @@ static int __init longhaul_get_ranges (void)
break; break;
} }
break; break;
case 4:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
//TODO: Nehemiah may have borken MaxMHzBR.
// need to extrapolate from FSB.
invalue2 = longhaul.bits.MinMHzBR;
invalue = longhaul.bits.MaxMHzBR;
if (longhaul.bits.MaxMHzBR4)
invalue += 16;
maxmult=multipliers[invalue];
maxmult=longhaul_get_cpu_mult();
printk(KERN_INFO PFX " invalue: %ld maxmult: %d \n", invalue, maxmult);
printk(KERN_INFO PFX " invalue2: %ld \n", invalue2);
minmult=50;
switch (longhaul.bits.MaxMHzFSB) {
case 0x0: fsb=133;
break;
case 0x1: fsb=100;
break;
case 0x2: printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
return -EINVAL;
case 0x3: fsb=66;
break;
}
break;
} }
dprintk (KERN_INFO PFX "MinMult=%d.%dx MaxMult=%d.%dx\n", dprintk (KERN_INFO PFX "MinMult=%d.%dx MaxMult=%d.%dx\n",
...@@ -430,12 +480,27 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy) ...@@ -430,12 +480,27 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy)
break; break;
case 9: case 9:
cpuname = "C3 'Nehemiah' [C5N]"; longhaul_version=4;
longhaul_version=2;
numscales=32; numscales=32;
memcpy (clock_ratio, nehemiah_clock_ratio, sizeof(nehemiah_clock_ratio)); switch (c->x86_mask) {
memcpy (eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr)); case 0 ... 1:
cpuname = "C3 'Nehemiah A' [C5N]";
memcpy (clock_ratio, nehemiah_a_clock_ratio, sizeof(nehemiah_a_clock_ratio));
memcpy (eblcr_table, nehemiah_a_eblcr, sizeof(nehemiah_a_eblcr));
break;
case 2 ... 4:
cpuname = "C3 'Nehemiah B' [C5N]";
memcpy (clock_ratio, nehemiah_b_clock_ratio, sizeof(nehemiah_b_clock_ratio));
memcpy (eblcr_table, nehemiah_b_eblcr, sizeof(nehemiah_b_eblcr));
break;
case 5 ... 15:
cpuname = "C3 'Nehemiah C' [C5N]";
memcpy (clock_ratio, nehemiah_c_clock_ratio, sizeof(nehemiah_c_clock_ratio));
memcpy (eblcr_table, nehemiah_c_eblcr, sizeof(nehemiah_c_eblcr));
break; break;
}
break;
default: default:
cpuname = "Unknown"; cpuname = "Unknown";
......
...@@ -234,7 +234,8 @@ static int __initdata ezrat_eblcr[32] = { ...@@ -234,7 +234,8 @@ static int __initdata ezrat_eblcr[32] = {
/* /*
* VIA C3 Nehemiah */ * VIA C3 Nehemiah */
static int __initdata nehemiah_clock_ratio[32] = {
static int __initdata nehemiah_a_clock_ratio[32] = {
100, /* 0000 -> 10.0x */ 100, /* 0000 -> 10.0x */
160, /* 0001 -> 16.0x */ 160, /* 0001 -> 16.0x */
-1, /* 0010 -> RESERVED */ -1, /* 0010 -> RESERVED */
...@@ -251,7 +252,41 @@ static int __initdata nehemiah_clock_ratio[32] = { ...@@ -251,7 +252,41 @@ static int __initdata nehemiah_clock_ratio[32] = {
75, /* 1101 -> 7.5x */ 75, /* 1101 -> 7.5x */
85, /* 1110 -> 8.5x */ 85, /* 1110 -> 8.5x */
120, /* 1111 -> 12.0x */ 120, /* 1111 -> 12.0x */
100, /* 0000 -> 10.0x */
-1, /* 0001 -> RESERVED */
120, /* 0010 -> 12.0x */
90, /* 0011 -> 9.0x */
105, /* 0100 -> 10.5x */
115, /* 0101 -> 11.5x */
125, /* 0110 -> 12.5x */
135, /* 0111 -> 13.5x */
140, /* 1000 -> 14.0x */
150, /* 1001 -> 15.0x */
160, /* 1010 -> 16.0x */
130, /* 1011 -> 13.0x */
145, /* 1100 -> 14.5x */
155, /* 1101 -> 15.5x */
-1, /* 1110 -> RESERVED (13.0x) */
120, /* 1111 -> 12.0x */
};
static int __initdata nehemiah_b_clock_ratio[32] = {
100, /* 0000 -> 10.0x */
160, /* 0001 -> 16.0x */
-1, /* 0010 -> RESERVED */
90, /* 0011 -> 9.0x */
95, /* 0100 -> 9.5x */
-1, /* 0101 -> RESERVED */
-1, /* 0110 -> RESERVED */
55, /* 0111 -> 5.5x */
60, /* 1000 -> 6.0x */
70, /* 1001 -> 7.0x */
80, /* 1010 -> 8.0x */
50, /* 1011 -> 5.0x */
65, /* 1100 -> 6.5x */
75, /* 1101 -> 7.5x */
85, /* 1110 -> 8.5x */
120, /* 1111 -> 12.0x */
100, /* 0000 -> 10.0x */ 100, /* 0000 -> 10.0x */
110, /* 0001 -> 11.0x */ 110, /* 0001 -> 11.0x */
120, /* 0010 -> 12.0x */ 120, /* 0010 -> 12.0x */
...@@ -266,11 +301,81 @@ static int __initdata nehemiah_clock_ratio[32] = { ...@@ -266,11 +301,81 @@ static int __initdata nehemiah_clock_ratio[32] = {
130, /* 1011 -> 13.0x */ 130, /* 1011 -> 13.0x */
145, /* 1100 -> 14.5x */ 145, /* 1100 -> 14.5x */
155, /* 1101 -> 15.5x */ 155, /* 1101 -> 15.5x */
-1, /* 1110 -> RESERVED */ -1, /* 1110 -> RESERVED (13.0x) */
120, /* 1111 -> 12.0x */
};
static int __initdata nehemiah_c_clock_ratio[32] = {
100, /* 0000 -> 10.0x */
160, /* 0001 -> 16.0x */
40, /* 0010 -> RESERVED */
90, /* 0011 -> 9.0x */
95, /* 0100 -> 9.5x */
-1, /* 0101 -> RESERVED */
45, /* 0110 -> RESERVED */
55, /* 0111 -> 5.5x */
60, /* 1000 -> 6.0x */
70, /* 1001 -> 7.0x */
80, /* 1010 -> 8.0x */
50, /* 1011 -> 5.0x */
65, /* 1100 -> 6.5x */
75, /* 1101 -> 7.5x */
85, /* 1110 -> 8.5x */
120, /* 1111 -> 12.0x */
100, /* 0000 -> 10.0x */
110, /* 0001 -> 11.0x */
120, /* 0010 -> 12.0x */
90, /* 0011 -> 9.0x */
105, /* 0100 -> 10.5x */
115, /* 0101 -> 11.5x */
125, /* 0110 -> 12.5x */
135, /* 0111 -> 13.5x */
140, /* 1000 -> 14.0x */
150, /* 1001 -> 15.0x */
160, /* 1010 -> 16.0x */
130, /* 1011 -> 13.0x */
145, /* 1100 -> 14.5x */
155, /* 1101 -> 15.5x */
-1, /* 1110 -> RESERVED (13.0x) */
120, /* 1111 -> 12.0x */ 120, /* 1111 -> 12.0x */
}; };
static int __initdata nehemiah_eblcr[32] = { static int __initdata nehemiah_a_eblcr[32] = {
50, /* 0000 -> 5.0x */
160, /* 0001 -> 16.0x */
-1, /* 0010 -> RESERVED */
100, /* 0011 -> 10.0x */
55, /* 0100 -> 5.5x */
-1, /* 0101 -> RESERVED */
-1, /* 0110 -> RESERVED */
95, /* 0111 -> 9.5x */
90, /* 1000 -> 9.0x */
70, /* 1001 -> 7.0x */
80, /* 1010 -> 8.0x */
60, /* 1011 -> 6.0x */
120, /* 1100 -> 12.0x */
75, /* 1101 -> 7.5x */
85, /* 1110 -> 8.5x */
65, /* 1111 -> 6.5x */
90, /* 0000 -> 9.0x */
-1, /* 0001 -> RESERVED */
120, /* 0010 -> 12.0x */
100, /* 0011 -> 10.0x */
135, /* 0100 -> 13.5x */
115, /* 0101 -> 11.5x */
125, /* 0110 -> 12.5x */
105, /* 0111 -> 10.5x */
130, /* 1000 -> 13.0x */
150, /* 1001 -> 15.0x */
160, /* 1010 -> 16.0x */
140, /* 1011 -> 14.0x */
120, /* 1100 -> 12.0x */
155, /* 1101 -> 15.5x */
-1, /* 1110 -> RESERVED (13.0x) */
145 /* 1111 -> 14.5x */
/* end of table */
};
static int __initdata nehemiah_b_eblcr[32] = {
50, /* 0000 -> 5.0x */ 50, /* 0000 -> 5.0x */
160, /* 0001 -> 16.0x */ 160, /* 0001 -> 16.0x */
-1, /* 0010 -> RESERVED */ -1, /* 0010 -> RESERVED */
...@@ -287,7 +392,6 @@ static int __initdata nehemiah_eblcr[32] = { ...@@ -287,7 +392,6 @@ static int __initdata nehemiah_eblcr[32] = {
75, /* 1101 -> 7.5x */ 75, /* 1101 -> 7.5x */
85, /* 1110 -> 8.5x */ 85, /* 1110 -> 8.5x */
65, /* 1111 -> 6.5x */ 65, /* 1111 -> 6.5x */
90, /* 0000 -> 9.0x */ 90, /* 0000 -> 9.0x */
110, /* 0001 -> 11.0x */ 110, /* 0001 -> 11.0x */
120, /* 0010 -> 12.0x */ 120, /* 0010 -> 12.0x */
...@@ -302,9 +406,46 @@ static int __initdata nehemiah_eblcr[32] = { ...@@ -302,9 +406,46 @@ static int __initdata nehemiah_eblcr[32] = {
140, /* 1011 -> 14.0x */ 140, /* 1011 -> 14.0x */
120, /* 1100 -> 12.0x */ 120, /* 1100 -> 12.0x */
155, /* 1101 -> 15.5x */ 155, /* 1101 -> 15.5x */
-1, /* 1110 -> RESERVED */ -1, /* 1110 -> RESERVED (13.0x) */
-1, /* 1111 -> RESERVED */ 145 /* 1111 -> 14.5x */
/* end of table */
}; };
static int __initdata nehemiah_c_eblcr[32] = {
50, /* 0000 -> 5.0x */
160, /* 0001 -> 16.0x */
40, /* 0010 -> RESERVED */
100, /* 0011 -> 10.0x */
55, /* 0100 -> 5.5x */
-1, /* 0101 -> RESERVED */
45, /* 0110 -> RESERVED */
95, /* 0111 -> 9.5x */
90, /* 1000 -> 9.0x */
70, /* 1001 -> 7.0x */
80, /* 1010 -> 8.0x */
60, /* 1011 -> 6.0x */
120, /* 1100 -> 12.0x */
75, /* 1101 -> 7.5x */
85, /* 1110 -> 8.5x */
65, /* 1111 -> 6.5x */
90, /* 0000 -> 9.0x */
110, /* 0001 -> 11.0x */
120, /* 0010 -> 12.0x */
100, /* 0011 -> 10.0x */
135, /* 0100 -> 13.5x */
115, /* 0101 -> 11.5x */
125, /* 0110 -> 12.5x */
105, /* 0111 -> 10.5x */
130, /* 1000 -> 13.0x */
150, /* 1001 -> 15.0x */
160, /* 1010 -> 16.0x */
140, /* 1011 -> 14.0x */
120, /* 1100 -> 12.0x */
155, /* 1101 -> 15.5x */
-1, /* 1110 -> RESERVED (13.0x) */
145 /* 1111 -> 14.5x */
/* end of table */
};
/* /*
* Voltage scales. Div/Mod by 1000 to get actual voltage. * Voltage scales. Div/Mod by 1000 to get actual voltage.
* Which scale to use depends on the VRM type in use. * Which scale to use depends on the VRM type in use.
......
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