aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2008-01-30 07:32:41 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:32:41 -0500
commitddb25f9ac1c4b4f9ba0bdacd7850a921a0c6886c (patch)
tree285a144b79d8d17a35c7cd22ab1adb2ef6bdd0e8 /drivers/acpi
parent32c7553f824d0d76771404f0e11d6059f82e8de7 (diff)
x86: don't disable TSC in any C states on AMD Fam10h
The ACPI code currently disables TSC use in any C2 and C3 states. But the AMD Fam10h BKDG documents that the TSC will never stop in any C states when the CONSTANT_TSC bit is set. Make this disabling conditional on CONSTANT_TSC not set on AMD. I actually think this is true on Intel too for C2 states on CPUs with p-state invariant TSC, but this needs further discussions with Len to really confirm :-) So far it is only enabled on AMD. Cc: lenb@kernel.org Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_idle.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 0721a8183c89..eb1f82f79153 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -357,6 +357,26 @@ int acpi_processor_resume(struct acpi_device * device)
357 return 0; 357 return 0;
358} 358}
359 359
360#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
361static int tsc_halts_in_c(int state)
362{
363 switch (boot_cpu_data.x86_vendor) {
364 case X86_VENDOR_AMD:
365 /*
366 * AMD Fam10h TSC will tick in all
367 * C/P/S0/S1 states when this bit is set.
368 */
369 if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
370 return 0;
371 /*FALL THROUGH*/
372 case X86_VENDOR_INTEL:
373 /* Several cases known where TSC halts in C2 too */
374 default:
375 return state > ACPI_STATE_C1;
376 }
377}
378#endif
379
360#ifndef CONFIG_CPU_IDLE 380#ifndef CONFIG_CPU_IDLE
361static void acpi_processor_idle(void) 381static void acpi_processor_idle(void)
362{ 382{
@@ -516,7 +536,8 @@ static void acpi_processor_idle(void)
516 536
517#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 537#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
518 /* TSC halts in C2, so notify users */ 538 /* TSC halts in C2, so notify users */
519 mark_tsc_unstable("possible TSC halt in C2"); 539 if (tsc_halts_in_c(ACPI_STATE_C2))
540 mark_tsc_unstable("possible TSC halt in C2");
520#endif 541#endif
521 /* Compute time (ticks) that we were actually asleep */ 542 /* Compute time (ticks) that we were actually asleep */
522 sleep_ticks = ticks_elapsed(t1, t2); 543 sleep_ticks = ticks_elapsed(t1, t2);
@@ -580,7 +601,8 @@ static void acpi_processor_idle(void)
580 601
581#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 602#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
582 /* TSC halts in C3, so notify users */ 603 /* TSC halts in C3, so notify users */
583 mark_tsc_unstable("TSC halts in C3"); 604 if (tsc_halts_in_c(ACPI_STATE_C3))
605 mark_tsc_unstable("TSC halts in C3");
584#endif 606#endif
585 /* Compute time (ticks) that we were actually asleep */ 607 /* Compute time (ticks) that we were actually asleep */
586 sleep_ticks = ticks_elapsed(t1, t2); 608 sleep_ticks = ticks_elapsed(t1, t2);
@@ -1445,7 +1467,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
1445 1467
1446#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 1468#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1447 /* TSC could halt in idle, so notify users */ 1469 /* TSC could halt in idle, so notify users */
1448 mark_tsc_unstable("TSC halts in idle");; 1470 if (tsc_halts_in_c(cx->type))
1471 mark_tsc_unstable("TSC halts in idle");;
1449#endif 1472#endif
1450 sleep_ticks = ticks_elapsed(t1, t2); 1473 sleep_ticks = ticks_elapsed(t1, t2);
1451 1474
@@ -1556,7 +1579,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1556 1579
1557#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 1580#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1558 /* TSC could halt in idle, so notify users */ 1581 /* TSC could halt in idle, so notify users */
1559 mark_tsc_unstable("TSC halts in idle"); 1582 if (tsc_halts_in_c(ACPI_STATE_C3))
1583 mark_tsc_unstable("TSC halts in idle");
1560#endif 1584#endif
1561 sleep_ticks = ticks_elapsed(t1, t2); 1585 sleep_ticks = ticks_elapsed(t1, t2);
1562 /* Tell the scheduler how much we idled: */ 1586 /* Tell the scheduler how much we idled: */