Skip to content

Commit 46c435c

Browse files
committed
cpufreq: intel_pstate: Enable HWP without EPP if DEC is enabled
So far, HWP has never been enabled without EPP (Energy-Performance Preference) interface support, since the lack of the latter indicates an incomplete implementation of HWP, which was the case on early development vehicle platforms. However, HWP can be expected to work if DEC (Dynamic Efficiency Control) is enabled as indicated by setting bit 27 in MSR_IA32_POWER_CTL (DEC enable bit). Accordingly, allow HWP to be enabled if the EPP interface is not supported so long as DEC is enabled in the processor. Still, the EPP control sysfs interface is useless when EPP is not supported, so do not expose it in that case. Link: https://lore.kernel.org/linux-pm/20250904000608.260817-2-srinivas.pandruvada@linux.intel.com/ Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 995694e commit 46c435c

1 file changed

Lines changed: 56 additions & 16 deletions

File tree

drivers/cpufreq/intel_pstate.c

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -897,11 +897,19 @@ static ssize_t show_base_frequency(struct cpufreq_policy *policy, char *buf)
897897

898898
cpufreq_freq_attr_ro(base_frequency);
899899

900+
enum hwp_cpufreq_attr_index {
901+
HWP_BASE_FREQUENCY_INDEX = 0,
902+
HWP_PERFORMANCE_PREFERENCE_INDEX,
903+
HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX,
904+
HWP_CPUFREQ_ATTR_COUNT,
905+
};
906+
900907
static struct freq_attr *hwp_cpufreq_attrs[] = {
901-
&energy_performance_preference,
902-
&energy_performance_available_preferences,
903-
&base_frequency,
904-
NULL,
908+
[HWP_BASE_FREQUENCY_INDEX] = &base_frequency,
909+
[HWP_PERFORMANCE_PREFERENCE_INDEX] = &energy_performance_preference,
910+
[HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX] =
911+
&energy_performance_available_preferences,
912+
[HWP_CPUFREQ_ATTR_COUNT] = NULL,
905913
};
906914

907915
static bool no_cas __ro_after_init;
@@ -1370,6 +1378,9 @@ static void intel_pstate_hwp_offline(struct cpudata *cpu)
13701378
#define POWER_CTL_EE_ENABLE 1
13711379
#define POWER_CTL_EE_DISABLE 2
13721380

1381+
/* Enable bit for Dynamic Efficiency Control (DEC) */
1382+
#define POWER_CTL_DEC_ENABLE 27
1383+
13731384
static int power_ctl_ee_state;
13741385

13751386
static void set_power_ctl_ee_state(bool input)
@@ -3758,6 +3769,26 @@ static const struct x86_cpu_id intel_hybrid_scaling_factor[] = {
37583769
{}
37593770
};
37603771

3772+
static bool hwp_check_epp(void)
3773+
{
3774+
if (boot_cpu_has(X86_FEATURE_HWP_EPP))
3775+
return true;
3776+
3777+
/* Without EPP support, don't expose EPP-related sysfs attributes. */
3778+
hwp_cpufreq_attrs[HWP_PERFORMANCE_PREFERENCE_INDEX] = NULL;
3779+
hwp_cpufreq_attrs[HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX] = NULL;
3780+
3781+
return false;
3782+
}
3783+
3784+
static bool hwp_check_dec(void)
3785+
{
3786+
u64 power_ctl;
3787+
3788+
rdmsrq(MSR_IA32_POWER_CTL, power_ctl);
3789+
return !!(power_ctl & BIT(POWER_CTL_DEC_ENABLE));
3790+
}
3791+
37613792
static int __init intel_pstate_init(void)
37623793
{
37633794
static struct cpudata **_all_cpu_data;
@@ -3778,23 +3809,32 @@ static int __init intel_pstate_init(void)
37783809

37793810
id = x86_match_cpu(hwp_support_ids);
37803811
if (id) {
3781-
hwp_forced = intel_pstate_hwp_is_enabled();
3812+
bool epp_present = hwp_check_epp();
37823813

3783-
if (hwp_forced)
3814+
/*
3815+
* If HWP is enabled already, there is no choice but to deal
3816+
* with it.
3817+
*/
3818+
hwp_forced = intel_pstate_hwp_is_enabled();
3819+
if (hwp_forced) {
37843820
pr_info("HWP enabled by BIOS\n");
3785-
else if (no_load)
3821+
no_hwp = 0;
3822+
} else if (no_load) {
37863823
return -ENODEV;
3824+
} else if (!epp_present && !hwp_check_dec()) {
3825+
/*
3826+
* Avoid enabling HWP for processors without EPP support
3827+
* unless the Dynamic Efficiency Control (DEC) enable
3828+
* bit (MSR_IA32_POWER_CTL, bit 27) is set because that
3829+
* means incomplete HWP implementation which is a corner
3830+
* case and supporting it is generally problematic.
3831+
*/
3832+
no_hwp = 1;
3833+
}
37873834

37883835
copy_cpu_funcs(&core_funcs);
3789-
/*
3790-
* Avoid enabling HWP for processors without EPP support,
3791-
* because that means incomplete HWP implementation which is a
3792-
* corner case and supporting it is generally problematic.
3793-
*
3794-
* If HWP is enabled already, though, there is no choice but to
3795-
* deal with it.
3796-
*/
3797-
if ((!no_hwp && boot_cpu_has(X86_FEATURE_HWP_EPP)) || hwp_forced) {
3836+
3837+
if (!no_hwp) {
37983838
hwp_active = true;
37993839
hwp_mode_bdw = id->driver_data;
38003840
intel_pstate.attr = hwp_cpufreq_attrs;

0 commit comments

Comments
 (0)