diff options
Diffstat (limited to 'drivers/idle/intel_idle.c')
-rw-r--r-- | drivers/idle/intel_idle.c | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 4d140bbbe100..9b7ee7e427df 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -89,6 +89,7 @@ struct idle_cpu { | |||
89 | * Indicate which enable bits to clear here. | 89 | * Indicate which enable bits to clear here. |
90 | */ | 90 | */ |
91 | unsigned long auto_demotion_disable_flags; | 91 | unsigned long auto_demotion_disable_flags; |
92 | bool byt_auto_demotion_disable_flag; | ||
92 | bool disable_promotion_to_c1e; | 93 | bool disable_promotion_to_c1e; |
93 | }; | 94 | }; |
94 | 95 | ||
@@ -442,6 +443,66 @@ static struct cpuidle_state hsw_cstates[] = { | |||
442 | { | 443 | { |
443 | .enter = NULL } | 444 | .enter = NULL } |
444 | }; | 445 | }; |
446 | static struct cpuidle_state bdw_cstates[] = { | ||
447 | { | ||
448 | .name = "C1-BDW", | ||
449 | .desc = "MWAIT 0x00", | ||
450 | .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, | ||
451 | .exit_latency = 2, | ||
452 | .target_residency = 2, | ||
453 | .enter = &intel_idle }, | ||
454 | { | ||
455 | .name = "C1E-BDW", | ||
456 | .desc = "MWAIT 0x01", | ||
457 | .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, | ||
458 | .exit_latency = 10, | ||
459 | .target_residency = 20, | ||
460 | .enter = &intel_idle }, | ||
461 | { | ||
462 | .name = "C3-BDW", | ||
463 | .desc = "MWAIT 0x10", | ||
464 | .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
465 | .exit_latency = 40, | ||
466 | .target_residency = 100, | ||
467 | .enter = &intel_idle }, | ||
468 | { | ||
469 | .name = "C6-BDW", | ||
470 | .desc = "MWAIT 0x20", | ||
471 | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
472 | .exit_latency = 133, | ||
473 | .target_residency = 400, | ||
474 | .enter = &intel_idle }, | ||
475 | { | ||
476 | .name = "C7s-BDW", | ||
477 | .desc = "MWAIT 0x32", | ||
478 | .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
479 | .exit_latency = 166, | ||
480 | .target_residency = 500, | ||
481 | .enter = &intel_idle }, | ||
482 | { | ||
483 | .name = "C8-BDW", | ||
484 | .desc = "MWAIT 0x40", | ||
485 | .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
486 | .exit_latency = 300, | ||
487 | .target_residency = 900, | ||
488 | .enter = &intel_idle }, | ||
489 | { | ||
490 | .name = "C9-BDW", | ||
491 | .desc = "MWAIT 0x50", | ||
492 | .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
493 | .exit_latency = 600, | ||
494 | .target_residency = 1800, | ||
495 | .enter = &intel_idle }, | ||
496 | { | ||
497 | .name = "C10-BDW", | ||
498 | .desc = "MWAIT 0x60", | ||
499 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
500 | .exit_latency = 2600, | ||
501 | .target_residency = 7700, | ||
502 | .enter = &intel_idle }, | ||
503 | { | ||
504 | .enter = NULL } | ||
505 | }; | ||
445 | 506 | ||
446 | static struct cpuidle_state atom_cstates[] = { | 507 | static struct cpuidle_state atom_cstates[] = { |
447 | { | 508 | { |
@@ -613,6 +674,7 @@ static const struct idle_cpu idle_cpu_snb = { | |||
613 | static const struct idle_cpu idle_cpu_byt = { | 674 | static const struct idle_cpu idle_cpu_byt = { |
614 | .state_table = byt_cstates, | 675 | .state_table = byt_cstates, |
615 | .disable_promotion_to_c1e = true, | 676 | .disable_promotion_to_c1e = true, |
677 | .byt_auto_demotion_disable_flag = true, | ||
616 | }; | 678 | }; |
617 | 679 | ||
618 | static const struct idle_cpu idle_cpu_ivb = { | 680 | static const struct idle_cpu idle_cpu_ivb = { |
@@ -630,6 +692,11 @@ static const struct idle_cpu idle_cpu_hsw = { | |||
630 | .disable_promotion_to_c1e = true, | 692 | .disable_promotion_to_c1e = true, |
631 | }; | 693 | }; |
632 | 694 | ||
695 | static const struct idle_cpu idle_cpu_bdw = { | ||
696 | .state_table = bdw_cstates, | ||
697 | .disable_promotion_to_c1e = true, | ||
698 | }; | ||
699 | |||
633 | static const struct idle_cpu idle_cpu_avn = { | 700 | static const struct idle_cpu idle_cpu_avn = { |
634 | .state_table = avn_cstates, | 701 | .state_table = avn_cstates, |
635 | .disable_promotion_to_c1e = true, | 702 | .disable_promotion_to_c1e = true, |
@@ -658,7 +725,10 @@ static const struct x86_cpu_id intel_idle_ids[] = { | |||
658 | ICPU(0x3f, idle_cpu_hsw), | 725 | ICPU(0x3f, idle_cpu_hsw), |
659 | ICPU(0x45, idle_cpu_hsw), | 726 | ICPU(0x45, idle_cpu_hsw), |
660 | ICPU(0x46, idle_cpu_hsw), | 727 | ICPU(0x46, idle_cpu_hsw), |
661 | ICPU(0x4D, idle_cpu_avn), | 728 | ICPU(0x4d, idle_cpu_avn), |
729 | ICPU(0x3d, idle_cpu_bdw), | ||
730 | ICPU(0x4f, idle_cpu_bdw), | ||
731 | ICPU(0x56, idle_cpu_bdw), | ||
662 | {} | 732 | {} |
663 | }; | 733 | }; |
664 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); | 734 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); |
@@ -814,6 +884,11 @@ static int __init intel_idle_cpuidle_driver_init(void) | |||
814 | if (icpu->auto_demotion_disable_flags) | 884 | if (icpu->auto_demotion_disable_flags) |
815 | on_each_cpu(auto_demotion_disable, NULL, 1); | 885 | on_each_cpu(auto_demotion_disable, NULL, 1); |
816 | 886 | ||
887 | if (icpu->byt_auto_demotion_disable_flag) { | ||
888 | wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); | ||
889 | wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); | ||
890 | } | ||
891 | |||
817 | if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */ | 892 | if (icpu->disable_promotion_to_c1e) /* each-cpu is redundant */ |
818 | on_each_cpu(c1e_promotion_disable, NULL, 1); | 893 | on_each_cpu(c1e_promotion_disable, NULL, 1); |
819 | 894 | ||