aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafal Bilski <rafalbilski@interia.pl>2007-10-07 03:24:32 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-07 19:28:43 -0400
commit52a2638bff063acb28ba3355891c49cc240cc98b (patch)
treeae6f82aef50999049da63ceede4b958b703cff3e
parent74922be1485818ed368c4cf4f0b100f70bf01e08 (diff)
Longhaul: add auto enabled "revid_errata" option
VIA C3 Ezra-T has RevisionID equal to 1, but it needs RevisionKey to be 0 or CPU will ignore new frequency and will continue to work at old frequency. New "revid_errata" option will force RevisionKey to be set to 0, whatever RevisionID is. Additionaly "Longhaul" will not silently ignore unsuccessful transition. It will try to check if "revid_errata" or "disable_acpi_c3" options need to be enabled for this processor/system. Same for Longhaul ver. 2 support. It will be disabled if none of above options will work. Best case scenario (with patch apllied and v2 enabled): longhaul: VIA C3 'Ezra' [C5C] CPU detected. Longhaul v2 supported. longhaul: Using northbridge support. longhaul: VRM 8.5 longhaul: Max VID=1.350 Min VID=1.050, 13 possible voltage scales longhaul: f: 300000 kHz, index: 0, vid: 1050 mV [...] longhaul: Voltage scaling enabled. Worst case scenario: longhaul: VIA C3 'Ezra-T' [C5M] CPU detected. Powersaver supported. longhaul: Using northbridge support. longhaul: Using ACPI support. longhaul: VRM 8.5 longhaul: Claims to support voltage scaling but min & max are both 1.250. Voltage scaling disabled longhaul: Failed to set requested frequency! longhaul: Enabling "Ignore Revision ID" option. longhaul: Failed to set requested frequency! longhaul: Disabling ACPI C3 support. longhaul: Disabling "Ignore Revision ID" option. longhaul: Failed to set requested frequency! longhaul: Enabling "Ignore Revision ID" option. [akpm@linux-foundation.org: coding-style cleanups] Signed-off-by: Rafal Bilski <rafalbilski@interia.pl> Signed-off-by: Dave Jones <davej@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index ef8f0bc3fc71..f0cce3c2dc3a 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -76,6 +76,7 @@ static unsigned int longhaul_index;
76/* Module parameters */ 76/* Module parameters */
77static int scale_voltage; 77static int scale_voltage;
78static int disable_acpi_c3; 78static int disable_acpi_c3;
79static int revid_errata;
79 80
80#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) 81#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
81 82
@@ -168,7 +169,10 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
168 169
169 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val); 170 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
170 /* Setup new frequency */ 171 /* Setup new frequency */
171 longhaul.bits.RevisionKey = longhaul.bits.RevisionID; 172 if (!revid_errata)
173 longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
174 else
175 longhaul.bits.RevisionKey = 0;
172 longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf; 176 longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
173 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; 177 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
174 /* Setup new voltage */ 178 /* Setup new voltage */
@@ -272,7 +276,7 @@ static void longhaul_setstate(unsigned int table_index)
272 276
273 dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", 277 dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
274 fsb, mult/10, mult%10, print_speed(speed/1000)); 278 fsb, mult/10, mult%10, print_speed(speed/1000));
275 279retry_loop:
276 preempt_disable(); 280 preempt_disable();
277 local_irq_save(flags); 281 local_irq_save(flags);
278 282
@@ -344,6 +348,47 @@ static void longhaul_setstate(unsigned int table_index)
344 preempt_enable(); 348 preempt_enable();
345 349
346 freqs.new = calc_speed(longhaul_get_cpu_mult()); 350 freqs.new = calc_speed(longhaul_get_cpu_mult());
351 /* Check if requested frequency is set. */
352 if (unlikely(freqs.new != speed)) {
353 printk(KERN_INFO PFX "Failed to set requested frequency!\n");
354 /* Revision ID = 1 but processor is expecting revision key
355 * equal to 0. Jumpers at the bottom of processor will change
356 * multiplier and FSB, but will not change bits in Longhaul
357 * MSR nor enable voltage scaling. */
358 if (!revid_errata) {
359 printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" "
360 "option.\n");
361 revid_errata = 1;
362 msleep(200);
363 goto retry_loop;
364 }
365 /* Why ACPI C3 sometimes doesn't work is a mystery for me.
366 * But it does happen. Processor is entering ACPI C3 state,
367 * but it doesn't change frequency. I tried poking various
368 * bits in northbridge registers, but without success. */
369 if (longhaul_flags & USE_ACPI_C3) {
370 printk(KERN_INFO PFX "Disabling ACPI C3 support.\n");
371 longhaul_flags &= ~USE_ACPI_C3;
372 if (revid_errata) {
373 printk(KERN_INFO PFX "Disabling \"Ignore "
374 "Revision ID\" option.\n");
375 revid_errata = 0;
376 }
377 msleep(200);
378 goto retry_loop;
379 }
380 /* This shouldn't happen. Longhaul ver. 2 was reported not
381 * working on processors without voltage scaling, but with
382 * RevID = 1. RevID errata will make things right. Just
383 * to be 100% sure. */
384 if (longhaul_version == TYPE_LONGHAUL_V2) {
385 printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n");
386 longhaul_version = TYPE_LONGHAUL_V1;
387 msleep(200);
388 goto retry_loop;
389 }
390 }
391 /* Report true CPU frequency */
347 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 392 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
348 393
349 if (!bm_timeout) 394 if (!bm_timeout)
@@ -956,11 +1001,20 @@ static void __exit longhaul_exit(void)
956 kfree(longhaul_table); 1001 kfree(longhaul_table);
957} 1002}
958 1003
1004/* Even if BIOS is exporting ACPI C3 state, and it is used
1005 * with success when CPU is idle, this state doesn't
1006 * trigger frequency transition in some cases. */
959module_param (disable_acpi_c3, int, 0644); 1007module_param (disable_acpi_c3, int, 0644);
960MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support"); 1008MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
961 1009/* Change CPU voltage with frequency. Very usefull to save
1010 * power, but most VIA C3 processors aren't supporting it. */
962module_param (scale_voltage, int, 0644); 1011module_param (scale_voltage, int, 0644);
963MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); 1012MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
1013/* Force revision key to 0 for processors which doesn't
1014 * support voltage scaling, but are introducing itself as
1015 * such. */
1016module_param(revid_errata, int, 0644);
1017MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
964 1018
965MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); 1019MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
966MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); 1020MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");