Skip to content

Commit 9edf3c0

Browse files
dedekindrafaeljw
authored andcommitted
intel_idle: add SPR support
Add Sapphire Rapids Xeon support. Up until very recently, the C1 and C1E C-states were independent, but this has changed in some new chips, including Sapphire Rapids Xeon (SPR). In these chips the C1 and C1E states cannot be enabled at the same time. The "C1E promotion" bit in 'MSR_IA32_POWER_CTL' also has its semantics changed a bit. Here are the C1, C1E, and "C1E promotion" bit rules on Xeons before SPR. 1. If C1E promotion bit is disabled. a. C1 requests end up with C1 C-state. b. C1E requests end up with C1E C-state. 2. If C1E promotion bit is enabled. a. C1 requests end up with C1E C-state. b. C1E requests end up with C1E C-state. Here are the C1, C1E, and "C1E promotion" bit rules on Sapphire Rapids Xeon. 1. If C1E promotion bit is disabled. a. C1 requests end up with C1 C-state. b. C1E requests end up with C1 C-state. 2. If C1E promotion bit is enabled. a. C1 requests end up with C1E C-state. b. C1E requests end up with C1E C-state. Before SPR Xeon, the 'intel_idle' driver was disabling C1E promotion and was exposing C1 and C1E as independent C-states. But on SPR, C1 and C1E cannot be enabled at the same time. This patch adds both C1 and C1E states. However, C1E is marked as with the "CPUIDLE_FLAG_UNUSABLE" flag, which means that in won't be registered by default. The C1E promotion bit will be cleared, which means that by default only C1 and C6 will be registered on SPR. The next patch will add an option for enabling C1E and disabling C1 on SPR. Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent eb087f3 commit 9edf3c0

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

drivers/idle/intel_idle.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,46 @@ static struct cpuidle_state icx_cstates[] __initdata = {
761761
.enter = NULL }
762762
};
763763

764+
/*
765+
* On Sapphire Rapids Xeon C1 has to be disabled if C1E is enabled, and vice
766+
* versa. On SPR C1E is enabled only if "C1E promotion" bit is set in
767+
* MSR_IA32_POWER_CTL. But in this case there effectively no C1, because C1
768+
* requests are promoted to C1E. If the "C1E promotion" bit is cleared, then
769+
* both C1 and C1E requests end up with C1, so there is effectively no C1E.
770+
*
771+
* By default we enable C1 and disable C1E by marking it with
772+
* 'CPUIDLE_FLAG_UNUSABLE'.
773+
*/
774+
static struct cpuidle_state spr_cstates[] __initdata = {
775+
{
776+
.name = "C1",
777+
.desc = "MWAIT 0x00",
778+
.flags = MWAIT2flg(0x00),
779+
.exit_latency = 1,
780+
.target_residency = 1,
781+
.enter = &intel_idle,
782+
.enter_s2idle = intel_idle_s2idle, },
783+
{
784+
.name = "C1E",
785+
.desc = "MWAIT 0x01",
786+
.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE | \
787+
CPUIDLE_FLAG_UNUSABLE,
788+
.exit_latency = 2,
789+
.target_residency = 4,
790+
.enter = &intel_idle,
791+
.enter_s2idle = intel_idle_s2idle, },
792+
{
793+
.name = "C6",
794+
.desc = "MWAIT 0x20",
795+
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
796+
.exit_latency = 290,
797+
.target_residency = 800,
798+
.enter = &intel_idle,
799+
.enter_s2idle = intel_idle_s2idle, },
800+
{
801+
.enter = NULL }
802+
};
803+
764804
static struct cpuidle_state atom_cstates[] __initdata = {
765805
{
766806
.name = "C1E",
@@ -1104,6 +1144,12 @@ static const struct idle_cpu idle_cpu_icx __initconst = {
11041144
.use_acpi = true,
11051145
};
11061146

1147+
static const struct idle_cpu idle_cpu_spr __initconst = {
1148+
.state_table = spr_cstates,
1149+
.disable_promotion_to_c1e = true,
1150+
.use_acpi = true,
1151+
};
1152+
11071153
static const struct idle_cpu idle_cpu_avn __initconst = {
11081154
.state_table = avn_cstates,
11091155
.disable_promotion_to_c1e = true,
@@ -1166,6 +1212,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
11661212
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx),
11671213
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx),
11681214
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx),
1215+
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr),
11691216
X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl),
11701217
X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl),
11711218
X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt),

0 commit comments

Comments
 (0)