diff options
| author | Rafal Bilski <rafalbilski@interia.pl> | 2007-10-07 03:24:32 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-07 19:28:43 -0400 |
| commit | 52a2638bff063acb28ba3355891c49cc240cc98b (patch) | |
| tree | ae6f82aef50999049da63ceede4b958b703cff3e | |
| parent | 74922be1485818ed368c4cf4f0b100f70bf01e08 (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.c | 60 |
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 */ |
| 77 | static int scale_voltage; | 77 | static int scale_voltage; |
| 78 | static int disable_acpi_c3; | 78 | static int disable_acpi_c3; |
| 79 | static 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 | 279 | retry_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. */ | ||
| 959 | module_param (disable_acpi_c3, int, 0644); | 1007 | module_param (disable_acpi_c3, int, 0644); |
| 960 | MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support"); | 1008 | MODULE_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. */ | ||
| 962 | module_param (scale_voltage, int, 0644); | 1011 | module_param (scale_voltage, int, 0644); |
| 963 | MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); | 1012 | MODULE_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. */ | ||
| 1016 | module_param(revid_errata, int, 0644); | ||
| 1017 | MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); | ||
| 964 | 1018 | ||
| 965 | MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); | 1019 | MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); |
| 966 | MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); | 1020 | MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); |
