Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Rafal Bilski and committed by
Linus Torvalds
52a2638b 74922be1

+57 -3
+57 -3
arch/i386/kernel/cpu/cpufreq/longhaul.c
··· 76 76 /* Module parameters */ 77 77 static int scale_voltage; 78 78 static int disable_acpi_c3; 79 + static int revid_errata; 79 80 80 81 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) 81 82 ··· 169 168 170 169 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val); 171 170 /* Setup new frequency */ 172 - longhaul.bits.RevisionKey = longhaul.bits.RevisionID; 171 + if (!revid_errata) 172 + longhaul.bits.RevisionKey = longhaul.bits.RevisionID; 173 + else 174 + longhaul.bits.RevisionKey = 0; 173 175 longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf; 174 176 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; 175 177 /* Setup new voltage */ ··· 276 272 277 273 dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", 278 274 fsb, mult/10, mult%10, print_speed(speed/1000)); 279 - 275 + retry_loop: 280 276 preempt_disable(); 281 277 local_irq_save(flags); 282 278 ··· 348 344 preempt_enable(); 349 345 350 346 freqs.new = calc_speed(longhaul_get_cpu_mult()); 347 + /* Check if requested frequency is set. */ 348 + if (unlikely(freqs.new != speed)) { 349 + printk(KERN_INFO PFX "Failed to set requested frequency!\n"); 350 + /* Revision ID = 1 but processor is expecting revision key 351 + * equal to 0. Jumpers at the bottom of processor will change 352 + * multiplier and FSB, but will not change bits in Longhaul 353 + * MSR nor enable voltage scaling. */ 354 + if (!revid_errata) { 355 + printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" " 356 + "option.\n"); 357 + revid_errata = 1; 358 + msleep(200); 359 + goto retry_loop; 360 + } 361 + /* Why ACPI C3 sometimes doesn't work is a mystery for me. 362 + * But it does happen. Processor is entering ACPI C3 state, 363 + * but it doesn't change frequency. I tried poking various 364 + * bits in northbridge registers, but without success. */ 365 + if (longhaul_flags & USE_ACPI_C3) { 366 + printk(KERN_INFO PFX "Disabling ACPI C3 support.\n"); 367 + longhaul_flags &= ~USE_ACPI_C3; 368 + if (revid_errata) { 369 + printk(KERN_INFO PFX "Disabling \"Ignore " 370 + "Revision ID\" option.\n"); 371 + revid_errata = 0; 372 + } 373 + msleep(200); 374 + goto retry_loop; 375 + } 376 + /* This shouldn't happen. Longhaul ver. 2 was reported not 377 + * working on processors without voltage scaling, but with 378 + * RevID = 1. RevID errata will make things right. Just 379 + * to be 100% sure. */ 380 + if (longhaul_version == TYPE_LONGHAUL_V2) { 381 + printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n"); 382 + longhaul_version = TYPE_LONGHAUL_V1; 383 + msleep(200); 384 + goto retry_loop; 385 + } 386 + } 387 + /* Report true CPU frequency */ 351 388 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 352 389 353 390 if (!bm_timeout) ··· 1001 956 kfree(longhaul_table); 1002 957 } 1003 958 959 + /* Even if BIOS is exporting ACPI C3 state, and it is used 960 + * with success when CPU is idle, this state doesn't 961 + * trigger frequency transition in some cases. */ 1004 962 module_param (disable_acpi_c3, int, 0644); 1005 963 MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support"); 1006 - 964 + /* Change CPU voltage with frequency. Very usefull to save 965 + * power, but most VIA C3 processors aren't supporting it. */ 1007 966 module_param (scale_voltage, int, 0644); 1008 967 MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); 968 + /* Force revision key to 0 for processors which doesn't 969 + * support voltage scaling, but are introducing itself as 970 + * such. */ 971 + module_param(revid_errata, int, 0644); 972 + MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); 1009 973 1010 974 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); 1011 975 MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");