Linux Documentation
 help / color / mirror / Atom feed
* [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode
@ 2026-06-30 18:58 K Prateek Nayak
  2026-06-30 18:58 ` [RFC PATCH 1/6] cpufreq/amd-pstate: Extract platform profile to EPP conversion into a helper K Prateek Nayak
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 18:58 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui,
	Jonathan Corbet, Shuah Khan
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Like custom_epp, move dnamic_epp functionality into a
energy_performance_preference selection which makes the integration more
natural with the rest of the driver functionality.

RFC is mainly to check if this is a good idea and if the "dynamic_epp"
sysfs needs to be retained? I've retained it in the series, changing it
to a RO attribute to reflect if the feature is disabled from kenel
cmdline but it seems unnecessary with the feature available as an
"energy_performance_preference" which can be toggled anytime.

Series is based on linux-pm:bleeding-edge at commit 03842bb4dfb5
("Merge branch 'experimental/acpi-driver-work' into bleeding-edge")
(30-06-2026) with Marco's series from [1] applied on top.

[1] https://lore.kernel.org/lkml/20260609073042.81275-1-scardracs@disroot.org/
---
K Prateek Nayak (6):
  cpufreq/amd-pstate: Extract platform profile to EPP conversion into a
    helper
  cpufreq/amd-pstate: Add dynamic EPP as an
    "energy_performance_preference" mode
  cpufreq/amd-pstate: Repurpose "amd_dynamic_epp" cmdline and
    corresponding sysfs
  Documentation/amd-pstate: Update dynamic_epp documentation with new
    behavior
  cpufreq/amd-pstate: Reduce the scope of exported symbols
  cpufreq/amd-pstate-ut: Add unit test for "dynamic" EPP mode

 Documentation/admin-guide/pm/amd-pstate.rst |  61 ++++--
 drivers/cpufreq/amd-pstate-ut.c             |  48 +++--
 drivers/cpufreq/amd-pstate.c                | 221 ++++++++++++--------
 drivers/cpufreq/amd-pstate.h                |   8 +
 4 files changed, 206 insertions(+), 132 deletions(-)


base-commit: 03842bb4dfb516e7c3c6323fede451823c4629dc
prerequisite-message-id: 20260609073042.81275-1-scardracs@disroot.org
prerequisite-patch-id: 15637b279250c6f653e42afb1c7ed7970be2627e
prerequisite-patch-id: f8c8f4064db0f33251d420723da8c92d9d803890
prerequisite-patch-id: 72386a2a5a24597eccbeb16624dcfd8b27770c16
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 1/6] cpufreq/amd-pstate: Extract platform profile to EPP conversion into a helper
  2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
@ 2026-06-30 18:58 ` K Prateek Nayak
  2026-07-01 21:31   ` Mario Limonciello
  2026-06-30 18:59 ` [RFC PATCH 2/6] cpufreq/amd-pstate: Add dynamic EPP as an "energy_performance_preference" mode K Prateek Nayak
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 18:58 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Avoid duplication by extracting the switch case that derives EPP based
on platform profile into the amd_pstate_get_epp_from_platform_profile()
helper.

No functional changes intended.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
 drivers/cpufreq/amd-pstate.c | 67 +++++++++++++++++-------------------
 1 file changed, 32 insertions(+), 35 deletions(-)

diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 20c30d14100f..1893b0054a6a 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1179,6 +1179,24 @@ static int amd_pstate_power_supply_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
+static int amd_pstate_get_epp_from_platform_profile(struct cpufreq_policy *policy,
+						    enum platform_profile_option profile)
+{
+	switch (profile) {
+	case PLATFORM_PROFILE_PERFORMANCE:
+		return AMD_CPPC_EPP_PERFORMANCE;
+	case PLATFORM_PROFILE_BALANCED:
+		return amd_pstate_get_balanced_epp(policy);
+	case PLATFORM_PROFILE_LOW_POWER:
+		return AMD_CPPC_EPP_POWERSAVE;
+	default:
+		break;
+	}
+
+	pr_err("Unknown Platform Profile %d\n", profile);
+	return -EOPNOTSUPP;
+}
+
 static int amd_pstate_profile_probe(void *drvdata, unsigned long *choices)
 {
 	set_bit(PLATFORM_PROFILE_LOW_POWER, choices);
@@ -1204,28 +1222,16 @@ static int amd_pstate_profile_set(struct device *dev,
 	struct amd_cpudata *cpudata = dev_get_drvdata(dev);
 	struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
 	int ret;
+	u8 epp;
 
-	switch (profile) {
-	case PLATFORM_PROFILE_LOW_POWER:
-		ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_POWERSAVE);
-		if (ret)
-			return ret;
-		break;
-	case PLATFORM_PROFILE_BALANCED:
-		ret = amd_pstate_set_epp(policy,
-					 amd_pstate_get_balanced_epp(policy));
-		if (ret)
-			return ret;
-		break;
-	case PLATFORM_PROFILE_PERFORMANCE:
-		ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_PERFORMANCE);
-		if (ret)
-			return ret;
-		break;
-	default:
-		pr_err("Unknown Platform Profile %d\n", profile);
-		return -EOPNOTSUPP;
-	}
+	ret = amd_pstate_get_epp_from_platform_profile(policy, profile);
+	if (ret < 0)
+		return ret;
+
+	epp = (u8)ret;
+	ret = amd_pstate_set_epp(policy, epp);
+	if (ret)
+		return ret;
 
 	cpudata->current_profile = profile;
 
@@ -1259,20 +1265,11 @@ static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
 	int ret;
 	u8 epp;
 
-	switch (cpudata->current_profile) {
-	case PLATFORM_PROFILE_PERFORMANCE:
-		epp = AMD_CPPC_EPP_PERFORMANCE;
-		break;
-	case PLATFORM_PROFILE_LOW_POWER:
-		epp = AMD_CPPC_EPP_POWERSAVE;
-		break;
-	case PLATFORM_PROFILE_BALANCED:
-		epp = amd_pstate_get_balanced_epp(policy);
-		break;
-	default:
-		pr_err("Unknown Platform Profile %d\n", cpudata->current_profile);
-		return -EOPNOTSUPP;
-	}
+	ret = amd_pstate_get_epp_from_platform_profile(policy, cpudata->current_profile);
+	if (ret < 0)
+		return ret;
+
+	epp = (u8)ret;
 	ret = amd_pstate_set_epp(policy, epp);
 	if (ret)
 		return ret;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 2/6] cpufreq/amd-pstate: Add dynamic EPP as an "energy_performance_preference" mode
  2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
  2026-06-30 18:58 ` [RFC PATCH 1/6] cpufreq/amd-pstate: Extract platform profile to EPP conversion into a helper K Prateek Nayak
@ 2026-06-30 18:59 ` K Prateek Nayak
  2026-07-01 21:33   ` Mario Limonciello
  2026-06-30 18:59 ` [RFC PATCH 3/6] cpufreq/amd-pstate: Repurpose "amd_dynamic_epp" cmdline and corresponding sysfs K Prateek Nayak
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 18:59 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Conver the global "dynamic_epp" toggle into a per-CPU
"energy_performance_preference" mode "dynamic" that allows toggling the
functionality of "dynamic_epp" at a per-CPU level.

Instead of being a system-wide toggle, users can opt into the
functionality of dynamic EPP on a per-CPU basis by switching to the
powersave governor and selecting the "dynamic" mode from the available
performance preferences.

Unlike the previous implementation that had to check for driver mode
before toggling on the functionality, block writes to certain sysfs
files, potentially disallow policy change, etc. the per-CPU toggle fits
naturally into the intended design and provides more granular control to
the user.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
 drivers/cpufreq/amd-pstate.c | 90 +++++++++++++++++++++++++++++++-----
 1 file changed, 79 insertions(+), 11 deletions(-)

diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 1893b0054a6a..c7eec6b96dcc 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -106,6 +106,7 @@ static struct quirk_entry *quirks;
  *	3		balance_power
  *	4		power
  *	5		custom (for raw EPP values)
+ *	6		dynamic (platform profile driven selection)
  */
 enum energy_perf_value_index {
 	EPP_INDEX_DEFAULT = 0,
@@ -114,6 +115,7 @@ enum energy_perf_value_index {
 	EPP_INDEX_BALANCE_POWERSAVE,
 	EPP_INDEX_POWERSAVE,
 	EPP_INDEX_CUSTOM,
+	EPP_INDEX_DYNAMIC,
 	EPP_INDEX_MAX,
 };
 
@@ -124,6 +126,7 @@ static const char * const energy_perf_strings[] = {
 	[EPP_INDEX_BALANCE_POWERSAVE] = "balance_power",
 	[EPP_INDEX_POWERSAVE] = "power",
 	[EPP_INDEX_CUSTOM] = "custom",
+	[EPP_INDEX_DYNAMIC] = "dynamic",
 };
 static_assert(ARRAY_SIZE(energy_perf_strings) == EPP_INDEX_MAX);
 
@@ -134,7 +137,7 @@ static unsigned int epp_values[] = {
 	[EPP_INDEX_BALANCE_POWERSAVE] = AMD_CPPC_EPP_BALANCE_POWERSAVE,
 	[EPP_INDEX_POWERSAVE] = AMD_CPPC_EPP_POWERSAVE,
 };
-static_assert(ARRAY_SIZE(epp_values) == EPP_INDEX_MAX - 1);
+static_assert(ARRAY_SIZE(epp_values) == EPP_INDEX_MAX - 2);
 
 typedef int (*cppc_mode_transition_fn)(int);
 
@@ -1262,6 +1265,7 @@ EXPORT_SYMBOL_GPL(amd_pstate_clear_dynamic_epp);
 static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
 {
 	struct amd_cpudata *cpudata = policy->driver_data;
+	u64 prev = READ_ONCE(cpudata->cppc_req_cached);
 	int ret;
 	u8 epp;
 
@@ -1302,6 +1306,9 @@ static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
 cleanup:
 	amd_pstate_clear_dynamic_epp(policy);
 
+	epp = FIELD_GET(AMD_CPPC_EPP_PERF_MASK, prev);
+	/* Restore previous EPP if toggling Dynamic EPP failed. */
+	amd_pstate_set_epp(policy, epp);
 	return ret;
 }
 
@@ -1372,14 +1379,22 @@ static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy,
 static ssize_t show_energy_performance_available_preferences(
 				struct cpufreq_policy *policy, char *buf)
 {
-	int offset = 0, i;
 	struct amd_cpudata *cpudata = policy->driver_data;
+	int i, max = EPP_INDEX_MAX, offset = 0;
 
 	if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
 		return sysfs_emit_at(buf, offset, "%s\n",
 				energy_perf_strings[EPP_INDEX_PERFORMANCE]);
 
-	for (i = 0; i < ARRAY_SIZE(energy_perf_strings); i++)
+	/*
+	 * Do not enumerate "dynamic" option only if disabled during boot.
+	 * Users can still opt in to dynamic EPP if platform (server) has
+	 * decided to keep it disabled by default.
+	 */
+	if (!dynamic_epp)
+		max = EPP_INDEX_DYNAMIC;
+
+	for (i = 0; i < max; i++)
 		offset += sysfs_emit_at(buf, offset, "%s ", energy_perf_strings[i]);
 
 	offset += sysfs_emit_at(buf, offset, "\n");
@@ -1395,11 +1410,6 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
 	bool raw_epp = false;
 	u8 epp;
 
-	if (cpudata->dynamic_epp) {
-		pr_debug("EPP cannot be set when dynamic EPP is enabled\n");
-		return -EBUSY;
-	}
-
 	/*
 	 * if the value matches a number, use that, otherwise see if
 	 * matches an index in the energy_perf_strings array
@@ -1410,6 +1420,26 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
 		ret = sysfs_match_string(energy_perf_strings, buf);
 		if (ret < 0 || ret == EPP_INDEX_CUSTOM)
 			return -EINVAL;
+
+		if (ret == EPP_INDEX_DYNAMIC) {
+			/* Dynamic EPP disabled at boot or by platform. */
+			if (!dynamic_epp)
+				return -EINVAL;
+			/*
+			 * Dynamic EPP was already enabled for this CPU.
+			 * Nothing to do.
+			 */
+			if (cpudata->dynamic_epp)
+				return count;
+
+			cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
+			ret = amd_pstate_set_dynamic_epp(policy);
+			if (ret)
+				return ret;
+
+			return count;
+		}
+
 		if (ret)
 			epp = epp_values[ret];
 		else
@@ -1421,6 +1451,13 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
 		return -EBUSY;
 	}
 
+	/*
+	 * Dynamic EPP was enabled previously!
+	 * Switch back to the static EPP mode.
+	 */
+	if (cpudata->dynamic_epp)
+		amd_pstate_clear_dynamic_epp(policy);
+
 	ret = amd_pstate_set_epp(policy, epp);
 	if (ret)
 		return ret;
@@ -1438,7 +1475,7 @@ ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *
 
 	epp = FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached);
 
-	if (cpudata->raw_epp)
+	if (!cpudata->dynamic_epp && cpudata->raw_epp)
 		return sysfs_emit(buf, "%u\n", epp);
 
 	switch (epp) {
@@ -1458,6 +1495,9 @@ ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *
 		return -EINVAL;
 	}
 
+	if (cpudata->dynamic_epp)
+		return sysfs_emit(buf, "dynamic(profile:%s)\n", energy_perf_strings[preference]);
+
 	return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
 }
 EXPORT_SYMBOL_GPL(show_energy_performance_preference);
@@ -1943,10 +1983,14 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
 		cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
 	}
 
-	if (dynamic_epp)
+	if (dynamic_epp) {
+		/* Dynamic EPP is only available with the POWERSAVE policy. */
+		policy->policy = CPUFREQ_POLICY_POWERSAVE;
 		ret = amd_pstate_set_dynamic_epp(policy);
-	else
+	} else {
 		ret = amd_pstate_set_epp(policy, cpudata->epp_default_dc);
+	}
+
 	if (ret)
 		goto free_cpudata1;
 
@@ -2018,6 +2062,30 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
 	if (!policy->cpuinfo.max_freq)
 		return -ENODEV;
 
+	/* Must be a switch between PERFORMANCE and POWERSAVE */
+	if (cpudata->policy != policy->policy) {
+		/*
+		 * Disable dynamic_epp when switching
+		 * out of CPUFREQ_POLICY_POWERSAVE.
+		 */
+		if (cpudata->dynamic_epp) {
+			WARN_ON_ONCE(cpudata->policy != CPUFREQ_POLICY_POWERSAVE);
+			amd_pstate_clear_dynamic_epp(policy);
+		}
+		/*
+		 * If dynamic_epp is enabled by default, toggle it on
+		 * when switching to CPUFREQ_POLICY_POWERSAVE.
+		 */
+		if (dynamic_epp) {
+			WARN_ON_ONCE(policy->policy != CPUFREQ_POLICY_POWERSAVE);
+
+			cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
+			ret = amd_pstate_set_dynamic_epp(policy);
+			if (ret)
+				return ret;
+		}
+	}
+
 	cpudata->policy = policy->policy;
 
 	ret = amd_pstate_epp_update_limit(policy, true);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 3/6] cpufreq/amd-pstate: Repurpose "amd_dynamic_epp" cmdline and corresponding sysfs
  2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
  2026-06-30 18:58 ` [RFC PATCH 1/6] cpufreq/amd-pstate: Extract platform profile to EPP conversion into a helper K Prateek Nayak
  2026-06-30 18:59 ` [RFC PATCH 2/6] cpufreq/amd-pstate: Add dynamic EPP as an "energy_performance_preference" mode K Prateek Nayak
@ 2026-06-30 18:59 ` K Prateek Nayak
  2026-07-01 21:40   ` Mario Limonciello
  2026-06-30 18:59 ` [RFC PATCH 4/6] Documentation/amd-pstate: Update dynamic_epp documentation with new behavior K Prateek Nayak
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 18:59 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Since dynamic_epp has been converted to an
"energy_performance_preference", toggling the feature via the sysfs file
is now redundant.

Repurpose "amd_dynamic_epp=enable" command line to opt into dynamic EPP
by default when the active driver is loaded, or switched into. The
"disable" counterpart will "dynamic" option out of
"energyy_performance_preference" to ensure dynamic EPP feature can never
be toggled.

Use a tri-state enum to differentiate if the user has supplied a command
line parameter or not to enable the feature by default vs keeping the
current defaults as is and allowing users to toggle it later via the
"dynamic" option in "energy_performance_preference" selection.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
 drivers/cpufreq/amd-pstate.c | 48 +++++++++---------------------------
 1 file changed, 12 insertions(+), 36 deletions(-)

diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index c7eec6b96dcc..61f30820d95a 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -82,12 +82,18 @@ struct quirk_entry {
 	u32 lowest_freq;
 };
 
+enum dynamic_epp_state {
+	DYNAMIC_EPP_USER_TOGGLE = -1,	/* User can toggle dynamic EPP. (Default) */
+	DYNAMIC_EPP_DISABLED,		/* Dynamic EPP disabled from command line. */
+	DYNAMIC_EPP_DEFAULT_ENABLED,	/* Dynamic EPP enabled from command line. */
+};
+
+static enum dynamic_epp_state dynamic_epp = DYNAMIC_EPP_USER_TOGGLE;
 static struct cpufreq_driver *current_pstate_driver;
 static struct cpufreq_driver amd_pstate_driver;
 static struct cpufreq_driver amd_pstate_epp_driver;
 static int cppc_state = AMD_PSTATE_UNDEFINED;
 static bool amd_pstate_prefcore = true;
-static bool dynamic_epp;
 static struct quirk_entry *quirks;
 
 /*
@@ -1839,39 +1845,9 @@ static ssize_t dynamic_epp_show(struct device *dev,
 	return sysfs_emit(buf, "%s\n", str_enabled_disabled(dynamic_epp));
 }
 
-static ssize_t dynamic_epp_store(struct device *a, struct device_attribute *b,
-				 const char *buf, size_t count)
-{
-	bool enabled;
-	int ret;
-
-	ret = kstrtobool(buf, &enabled);
-	if (ret)
-		return ret;
-
-	guard(mutex)(&amd_pstate_driver_lock);
-
-	if (cppc_state != AMD_PSTATE_ACTIVE) {
-		pr_debug("dynamic_epp can only be toggled in active mode\n");
-		return -EINVAL;
-	}
-
-	/* Nothing to do */
-	if (dynamic_epp == enabled)
-		return count;
-
-	/* reinitialize with desired dynamic EPP value */
-	dynamic_epp = enabled;
-	ret = amd_pstate_change_driver_mode(cppc_state);
-	if (ret)
-		dynamic_epp = false;
-
-	return ret ? ret : count;
-}
-
 static DEVICE_ATTR_RW(status);
 static DEVICE_ATTR_RO(prefcore);
-static DEVICE_ATTR_RW(dynamic_epp);
+static DEVICE_ATTR_RO(dynamic_epp);
 
 static struct attribute *pstate_global_attributes[] = {
 	&dev_attr_status.attr,
@@ -1983,7 +1959,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
 		cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
 	}
 
-	if (dynamic_epp) {
+	if (dynamic_epp == DYNAMIC_EPP_DEFAULT_ENABLED) {
 		/* Dynamic EPP is only available with the POWERSAVE policy. */
 		policy->policy = CPUFREQ_POLICY_POWERSAVE;
 		ret = amd_pstate_set_dynamic_epp(policy);
@@ -2076,7 +2052,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
 		 * If dynamic_epp is enabled by default, toggle it on
 		 * when switching to CPUFREQ_POLICY_POWERSAVE.
 		 */
-		if (dynamic_epp) {
+		if (dynamic_epp == DYNAMIC_EPP_DEFAULT_ENABLED) {
 			WARN_ON_ONCE(policy->policy != CPUFREQ_POLICY_POWERSAVE);
 
 			cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
@@ -2410,9 +2386,9 @@ static int __init amd_prefcore_param(char *str)
 static int __init amd_dynamic_epp_param(char *str)
 {
 	if (!strcmp(str, "disable"))
-		dynamic_epp = false;
+		dynamic_epp = DYNAMIC_EPP_DISABLED;
 	if (!strcmp(str, "enable"))
-		dynamic_epp = true;
+		dynamic_epp = DYNAMIC_EPP_DEFAULT_ENABLED;
 
 	return 0;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 4/6] Documentation/amd-pstate: Update dynamic_epp documentation with new behavior
  2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
                   ` (2 preceding siblings ...)
  2026-06-30 18:59 ` [RFC PATCH 3/6] cpufreq/amd-pstate: Repurpose "amd_dynamic_epp" cmdline and corresponding sysfs K Prateek Nayak
@ 2026-06-30 18:59 ` K Prateek Nayak
  2026-06-30 19:03 ` K Prateek Nayak
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 18:59 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui,
	Jonathan Corbet, Shuah Khan
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Update the admin-guide for dynamic_epp describing the latest integration
into energy_performance_preference selections.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
 Documentation/admin-guide/pm/amd-pstate.rst | 61 +++++++++++++--------
 1 file changed, 38 insertions(+), 23 deletions(-)

diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index a95e2ebce005..1afc2f8b3f0e 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -317,7 +317,10 @@ These profiles represent different hints that are provided
 to the low-level firmware about the user's desired energy vs efficiency
 tradeoff.  ``default`` represents the epp value is set by platform
 firmware. ``custom`` designates that integer values 0-255 may be written
-as well.  This attribute is read-only.
+as well. ``dynamic`` designates that the EPP is modified dynamically
+by the platform profile and the power supply status. See ``Dynamic energy
+performance profile`` section below to know more about the ``dynamic``
+mode. This attribute is read-only.
 
 ``energy_performance_preference``
 
@@ -326,13 +329,11 @@ and user can change current preference according to energy or performance needs
 Coarse named profiles are available in the attribute
 ``energy_performance_available_preferences``.
 Users can also write individual integer values between 0 to 255.
-When dynamic EPP is enabled, writes to energy_performance_preference are blocked
-even when EPP feature is enabled by platform firmware. Lower epp values shift the bias
-towards improved performance while a higher epp value shifts the bias towards
-power-savings. The exact impact can change from one platform to the other.
-If a valid integer was last written, then a number will be returned on future reads.
-If a valid string was last written then a string will be returned on future reads.
-This attribute is read-write.
+Lower epp values shift the bias towards improved performance while a higher epp
+value shifts the bias towards power-savings. The exact impact can change from
+one platform to the other. If a valid integer was last written, then a number
+will be returned on future reads. If a valid string was last written then a
+string will be returned on future reads. This attribute is read-write.
 
 ``boost``
 The `boost` sysfs attribute provides control over the CPU core
@@ -356,21 +357,35 @@ Other performance and frequency values can be read back from
 Dynamic energy performance profile
 ==================================
 The amd-pstate driver supports dynamically selecting the energy performance
-profile based on whether the machine is running on AC or DC power.
-
-Whether this behavior is enabled by default depends on the kernel command line option
-``amd_dynamic_epp`` is set. This behavior can also be overridden
-at runtime by the sysfs file ``/sys/devices/system/cpu/amd_pstate/dynamic_epp``.
-
-When set to enabled, the driver will select a different energy performance
-profile when the machine is running on battery or AC power. The driver will
-also register with the platform profile handler to receive notifications of
-user desired power state and react to those.
-When set to disabled, the driver will not change the energy performance profile
-based on the power source and will not react to user desired power state.
-
-Attempting to manually write to the ``energy_performance_preference`` sysfs
-file will fail when ``dynamic_epp`` is enabled.
+profile based on whether the machine is running on AC or DC power in active
+mode.
+
+The ``dynamic`` mode is listed in
+``/sys/devices/system/cpu/cpuX/cpufreq/energy_performance_available_preferences``
+when available while running under the ``powersave`` governor. The ``dynamic``
+mode can be toggled on by writing the same to the sysfs file
+``/sys/devices/system/cpu/cpuX/cpufreq/energy_performance_preference`` when
+available.
+
+When ``amd_dynamic_epp=disable`` is added to the kernel command line,
+``dynamic`` option is not available in
+``energy_performance_available_preferences`` and the feature cannot be toggled
+at runtime.
+
+When ``amd_dynamic_epp=enable`` is added to the kernel command line, ``dynamic``
+option is selected by default as ``energy_performance_preference`` when
+amd-pstate-epp driver is loaded.
+
+The availability of ``dynamic`` option as an ``energy_performance_preference``
+can be found by inspecting the sysfs files
+``/sys/devices/system/cpu/amd_pstate/dynamic_epp`` and
+``/sys/devices/system/cpu/cpuX/cpufreq/energy_performance_available_preferences``
+
+When ``energy_performance_preference`` is set to ``dynamic``, the driver will
+select a different energy performance profile when the machine is running on
+battery or AC power. The driver will also register with the platform profile
+handler to receive notifications of user desired power state and react to
+those.
 
 ``amd-pstate`` vs ``acpi-cpufreq``
 ======================================
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 4/6] Documentation/amd-pstate: Update dynamic_epp documentation with new behavior
  2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
                   ` (3 preceding siblings ...)
  2026-06-30 18:59 ` [RFC PATCH 4/6] Documentation/amd-pstate: Update dynamic_epp documentation with new behavior K Prateek Nayak
@ 2026-06-30 19:03 ` K Prateek Nayak
  2026-06-30 19:03 ` [RFC PATCH 5/6] cpufreq/amd-pstate: Reduce the scope of exported symbols K Prateek Nayak
  2026-06-30 19:03 ` [RFC PATCH 6/6] cpufreq/amd-pstate-ut: Add unit test for "dynamic" EPP mode K Prateek Nayak
  6 siblings, 0 replies; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 19:03 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui,
	Jonathan Corbet, Shuah Khan
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Update the admin-guide for dynamic_epp describing the latest integration
into energy_performance_preference selections.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
 Documentation/admin-guide/pm/amd-pstate.rst | 61 +++++++++++++--------
 1 file changed, 38 insertions(+), 23 deletions(-)

diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index a95e2ebce005..1afc2f8b3f0e 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -317,7 +317,10 @@ These profiles represent different hints that are provided
 to the low-level firmware about the user's desired energy vs efficiency
 tradeoff.  ``default`` represents the epp value is set by platform
 firmware. ``custom`` designates that integer values 0-255 may be written
-as well.  This attribute is read-only.
+as well. ``dynamic`` designates that the EPP is modified dynamically
+by the platform profile and the power supply status. See ``Dynamic energy
+performance profile`` section below to know more about the ``dynamic``
+mode. This attribute is read-only.
 
 ``energy_performance_preference``
 
@@ -326,13 +329,11 @@ and user can change current preference according to energy or performance needs
 Coarse named profiles are available in the attribute
 ``energy_performance_available_preferences``.
 Users can also write individual integer values between 0 to 255.
-When dynamic EPP is enabled, writes to energy_performance_preference are blocked
-even when EPP feature is enabled by platform firmware. Lower epp values shift the bias
-towards improved performance while a higher epp value shifts the bias towards
-power-savings. The exact impact can change from one platform to the other.
-If a valid integer was last written, then a number will be returned on future reads.
-If a valid string was last written then a string will be returned on future reads.
-This attribute is read-write.
+Lower epp values shift the bias towards improved performance while a higher epp
+value shifts the bias towards power-savings. The exact impact can change from
+one platform to the other. If a valid integer was last written, then a number
+will be returned on future reads. If a valid string was last written then a
+string will be returned on future reads. This attribute is read-write.
 
 ``boost``
 The `boost` sysfs attribute provides control over the CPU core
@@ -356,21 +357,35 @@ Other performance and frequency values can be read back from
 Dynamic energy performance profile
 ==================================
 The amd-pstate driver supports dynamically selecting the energy performance
-profile based on whether the machine is running on AC or DC power.
-
-Whether this behavior is enabled by default depends on the kernel command line option
-``amd_dynamic_epp`` is set. This behavior can also be overridden
-at runtime by the sysfs file ``/sys/devices/system/cpu/amd_pstate/dynamic_epp``.
-
-When set to enabled, the driver will select a different energy performance
-profile when the machine is running on battery or AC power. The driver will
-also register with the platform profile handler to receive notifications of
-user desired power state and react to those.
-When set to disabled, the driver will not change the energy performance profile
-based on the power source and will not react to user desired power state.
-
-Attempting to manually write to the ``energy_performance_preference`` sysfs
-file will fail when ``dynamic_epp`` is enabled.
+profile based on whether the machine is running on AC or DC power in active
+mode.
+
+The ``dynamic`` mode is listed in
+``/sys/devices/system/cpu/cpuX/cpufreq/energy_performance_available_preferences``
+when available while running under the ``powersave`` governor. The ``dynamic``
+mode can be toggled on by writing the same to the sysfs file
+``/sys/devices/system/cpu/cpuX/cpufreq/energy_performance_preference`` when
+available.
+
+When ``amd_dynamic_epp=disable`` is added to the kernel command line,
+``dynamic`` option is not available in
+``energy_performance_available_preferences`` and the feature cannot be toggled
+at runtime.
+
+When ``amd_dynamic_epp=enable`` is added to the kernel command line, ``dynamic``
+option is selected by default as ``energy_performance_preference`` when
+amd-pstate-epp driver is loaded.
+
+The availability of ``dynamic`` option as an ``energy_performance_preference``
+can be found by inspecting the sysfs files
+``/sys/devices/system/cpu/amd_pstate/dynamic_epp`` and
+``/sys/devices/system/cpu/cpuX/cpufreq/energy_performance_available_preferences``
+
+When ``energy_performance_preference`` is set to ``dynamic``, the driver will
+select a different energy performance profile when the machine is running on
+battery or AC power. The driver will also register with the platform profile
+handler to receive notifications of user desired power state and react to
+those.
 
 ``amd-pstate`` vs ``acpi-cpufreq``
 ======================================
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 5/6] cpufreq/amd-pstate: Reduce the scope of exported symbols
  2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
                   ` (4 preceding siblings ...)
  2026-06-30 19:03 ` K Prateek Nayak
@ 2026-06-30 19:03 ` K Prateek Nayak
  2026-07-01 21:38   ` Mario Limonciello
  2026-06-30 19:03 ` [RFC PATCH 6/6] cpufreq/amd-pstate-ut: Add unit test for "dynamic" EPP mode K Prateek Nayak
  6 siblings, 1 reply; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 19:03 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Symbols exported by amd-pstate.c are ever only needed for amd-pstate-ut.
Introduce EXPORT_SYMBOL_FOR_PSTATE_UT() to export these symbols
selectively to "amd-pstate-ut" namespace as opposed to all GPL modules.

No functional changes intended.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
 drivers/cpufreq/amd-pstate.c | 14 +++++++-------
 drivers/cpufreq/amd-pstate.h |  7 +++++++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 61f30820d95a..44c03b0be219 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -75,7 +75,7 @@ const char *amd_pstate_get_mode_string(enum amd_pstate_mode mode)
 		mode = AMD_PSTATE_UNDEFINED;
 	return amd_pstate_mode_string[mode];
 }
-EXPORT_SYMBOL_GPL(amd_pstate_get_mode_string);
+EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_get_mode_string);
 
 struct quirk_entry {
 	u32 nominal_freq;
@@ -1266,7 +1266,7 @@ void amd_pstate_clear_dynamic_epp(struct cpufreq_policy *policy)
 	kfree(cpudata->profile_name);
 	cpudata->dynamic_epp = false;
 }
-EXPORT_SYMBOL_GPL(amd_pstate_clear_dynamic_epp);
+EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_clear_dynamic_epp);
 
 static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
 {
@@ -1472,7 +1472,7 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
 
 	return count;
 }
-EXPORT_SYMBOL_GPL(store_energy_performance_preference);
+EXPORT_SYMBOL_FOR_PSTATE_UT(store_energy_performance_preference);
 
 ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *buf)
 {
@@ -1506,7 +1506,7 @@ ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *
 
 	return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
 }
-EXPORT_SYMBOL_GPL(show_energy_performance_preference);
+EXPORT_SYMBOL_FOR_PSTATE_UT(show_energy_performance_preference);
 
 static ssize_t store_amd_pstate_floor_freq(struct cpufreq_policy *policy,
 					   const char *buf, size_t count)
@@ -1606,7 +1606,7 @@ struct freq_attr **amd_pstate_get_current_attrs(void)
 		return NULL;
 	return current_pstate_driver->attr;
 }
-EXPORT_SYMBOL_GPL(amd_pstate_get_current_attrs);
+EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_get_current_attrs);
 
 static struct freq_attr **get_freq_attrs(void)
 {
@@ -1791,7 +1791,7 @@ int amd_pstate_get_status(void)
 {
 	return cppc_state;
 }
-EXPORT_SYMBOL_GPL(amd_pstate_get_status);
+EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_get_status);
 
 int amd_pstate_update_status(const char *buf, size_t size)
 {
@@ -1811,7 +1811,7 @@ int amd_pstate_update_status(const char *buf, size_t size)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(amd_pstate_update_status);
+EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_update_status);
 
 static ssize_t status_show(struct device *dev,
 			   struct device_attribute *attr, char *buf)
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
index 23e8baa05849..edd697a5e29f 100644
--- a/drivers/cpufreq/amd-pstate.h
+++ b/drivers/cpufreq/amd-pstate.h
@@ -11,6 +11,13 @@
 #include <linux/pm_qos.h>
 #include <linux/platform_profile.h>
 
+#if IS_MODULE(CONFIG_X86_AMD_PSTATE_UT)
+#define EXPORT_SYMBOL_FOR_PSTATE_UT(symbol) \
+	EXPORT_SYMBOL_FOR_MODULES(symbol, "amd-pstate-ut")
+#else
+#define EXPORT_SYMBOL_FOR_PSTATE_UT(symbol)
+#endif
+
 /*********************************************************************
  *                        AMD P-state INTERFACE                       *
  *********************************************************************/
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 6/6] cpufreq/amd-pstate-ut: Add unit test for "dynamic" EPP mode
  2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
                   ` (5 preceding siblings ...)
  2026-06-30 19:03 ` [RFC PATCH 5/6] cpufreq/amd-pstate: Reduce the scope of exported symbols K Prateek Nayak
@ 2026-06-30 19:03 ` K Prateek Nayak
  6 siblings, 0 replies; 12+ messages in thread
From: K Prateek Nayak @ 2026-06-30 19:03 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, K Prateek Nayak, linux-pm, linux-doc, linux-kernel

Extend the EPP unit test to cover the "dynamic" epp mode. Since
"dynamic_epp" is no longer a system-wide toggle, remove the legacy
"dynamic_epp" bits from the unit test.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
 drivers/cpufreq/amd-pstate-ut.c | 48 ++++++++++++++++++---------------
 drivers/cpufreq/amd-pstate.c    |  6 +++++
 drivers/cpufreq/amd-pstate.h    |  1 +
 3 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
index 735b29f76438..affe36218d73 100644
--- a/drivers/cpufreq/amd-pstate-ut.c
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -275,6 +275,7 @@ static int amd_pstate_set_mode(enum amd_pstate_mode mode)
 static int amd_pstate_ut_epp(u32 index)
 {
 	static const char * const epp_strings[] = {
+		"dynamic",
 		"power",
 		"balance_power",
 		"balance_performance",
@@ -282,10 +283,10 @@ static int amd_pstate_ut_epp(u32 index)
 	};
 	char *buf __free(cleanup_page) = NULL;
 	struct cpufreq_policy *policy = NULL;
+	unsigned long orig_dynamic_epp = 0;
 	enum amd_pstate_mode orig_mode;
 	struct amd_cpudata *cpudata;
 	unsigned long orig_policy;
-	bool orig_dynamic_epp;
 	int ret, cpu = 0;
 	u16 epp;
 	int i;
@@ -294,9 +295,11 @@ static int amd_pstate_ut_epp(u32 index)
 	if (!policy)
 		return -ENODEV;
 
-	cpudata = policy->driver_data;
 	orig_mode = amd_pstate_get_status();
-	orig_dynamic_epp = cpudata->dynamic_epp;
+	if (policy->driver_data) {
+		cpudata = policy->driver_data;
+		orig_dynamic_epp = cpudata->dynamic_epp;
+	}
 
 	/* Drop reference before potential driver change. */
 	cpufreq_cpu_put(policy);
@@ -321,16 +324,6 @@ static int amd_pstate_ut_epp(u32 index)
 	orig_policy = cpudata->policy;
 	cpudata->policy = CPUFREQ_POLICY_POWERSAVE;
 
-	/*
-	 * Disable dynamic EPP before running test. If "orig_dynamic_epp" is
-	 * true, the  driver will do a redundant switch at the end and there
-	 * is no need for enabling it again at the end of the test.
-	 */
-	if (cpudata->dynamic_epp) {
-		pr_debug("Dynamic EPP is enabled, disabling it\n");
-		amd_pstate_clear_dynamic_epp(policy);
-	}
-
 	for (epp = 0; epp <= U8_MAX; epp++) {
 		u8 val;
 
@@ -355,7 +348,8 @@ static int amd_pstate_ut_epp(u32 index)
 		}
 	}
 
-	for (i = 0; i < ARRAY_SIZE(epp_strings); i++) {
+	/* If dynamic EPP is disabled via cmdline, start at index 1. */
+	for (i = amd_pstate_dynamic_epp_disabled(); i < ARRAY_SIZE(epp_strings); i++) {
 		memset(buf, 0, PAGE_SIZE);
 		snprintf(buf, PAGE_SIZE, "%s", epp_strings[i]);
 		ret = store_energy_performance_preference(policy, buf, strlen(buf));
@@ -367,6 +361,11 @@ static int amd_pstate_ut_epp(u32 index)
 		if (ret < 0)
 			goto out;
 		strreplace(buf, '\n', '\0');
+		/*
+		 * "dynamic" mode reports the EPP as "dynamic(profile:X)"
+		 * Trim at "(" and just compare tie the epp string.
+		 */
+		strreplace(buf, '(', '\0');
 
 		if (strcmp(buf, epp_strings[i])) {
 			pr_err("String EPP value mismatch: %s != %s\n", buf, epp_strings[i]);
@@ -380,18 +379,23 @@ static int amd_pstate_ut_epp(u32 index)
 out:
 	if (policy) {
 		cpudata->policy = orig_policy;
+		/*
+		 * If the driver had enabled dynamic_epp to brgin with,
+		 * restore it here before dropping policy reference.
+		 */
+		if (orig_dynamic_epp) {
+			int ret2;
+
+			ret2 = store_energy_performance_preference(policy,
+								  epp_strings[0],
+								  strlen(epp_strings[0]));
+			if (!ret && (ret2 < 0))
+				ret = ret2;
+		}
 		up_write(&policy->rwsem);
 		cpufreq_cpu_put(policy);
 	}
 
-	if (orig_dynamic_epp) {
-		int ret2;
-
-		ret2 = amd_pstate_set_mode(AMD_PSTATE_DISABLE);
-		if (!ret && ret2)
-			ret = ret2;
-	}
-
 	if (orig_mode != amd_pstate_get_status()) {
 		int ret2;
 
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 44c03b0be219..e7f83482c8cb 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1253,6 +1253,12 @@ static const struct platform_profile_ops amd_pstate_profile_ops = {
 	.profile_get = amd_pstate_profile_get,
 };
 
+int amd_pstate_dynamic_epp_disabled(void)
+{
+	return !dynamic_epp;
+}
+EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_dynamic_epp_disabled);
+
 void amd_pstate_clear_dynamic_epp(struct cpufreq_policy *policy)
 {
 	struct amd_cpudata *cpudata = policy->driver_data;
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
index edd697a5e29f..bbde1d035071 100644
--- a/drivers/cpufreq/amd-pstate.h
+++ b/drivers/cpufreq/amd-pstate.h
@@ -160,6 +160,7 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
 				    const char *buf, size_t count);
 ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *buf);
 void amd_pstate_clear_dynamic_epp(struct cpufreq_policy *policy);
+int amd_pstate_dynamic_epp_disabled(void);
 
 struct freq_attr;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 1/6] cpufreq/amd-pstate: Extract platform profile to EPP conversion into a helper
  2026-06-30 18:58 ` [RFC PATCH 1/6] cpufreq/amd-pstate: Extract platform profile to EPP conversion into a helper K Prateek Nayak
@ 2026-07-01 21:31   ` Mario Limonciello
  0 siblings, 0 replies; 12+ messages in thread
From: Mario Limonciello @ 2026-07-01 21:31 UTC (permalink / raw)
  To: K Prateek Nayak, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, linux-pm, linux-doc, linux-kernel



On 6/30/26 13:58, K Prateek Nayak wrote:
> Avoid duplication by extracting the switch case that derives EPP based
> on platform profile into the amd_pstate_get_epp_from_platform_profile()
> helper.
> 
> No functional changes intended.
> 
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
> ---
>   drivers/cpufreq/amd-pstate.c | 67 +++++++++++++++++-------------------
>   1 file changed, 32 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 20c30d14100f..1893b0054a6a 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -1179,6 +1179,24 @@ static int amd_pstate_power_supply_notifier(struct notifier_block *nb,
>   	return NOTIFY_OK;
>   }
>   
> +static int amd_pstate_get_epp_from_platform_profile(struct cpufreq_policy *policy,
> +						    enum platform_profile_option profile)
> +{
> +	switch (profile) {
> +	case PLATFORM_PROFILE_PERFORMANCE:
> +		return AMD_CPPC_EPP_PERFORMANCE;
> +	case PLATFORM_PROFILE_BALANCED:
> +		return amd_pstate_get_balanced_epp(policy);
> +	case PLATFORM_PROFILE_LOW_POWER:
> +		return AMD_CPPC_EPP_POWERSAVE;
> +	default:
> +		break;
> +	}
> +
> +	pr_err("Unknown Platform Profile %d\n", profile);
> +	return -EOPNOTSUPP;
> +}
> +
>   static int amd_pstate_profile_probe(void *drvdata, unsigned long *choices)
>   {
>   	set_bit(PLATFORM_PROFILE_LOW_POWER, choices);
> @@ -1204,28 +1222,16 @@ static int amd_pstate_profile_set(struct device *dev,
>   	struct amd_cpudata *cpudata = dev_get_drvdata(dev);
>   	struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
>   	int ret;
> +	u8 epp;
>   
> -	switch (profile) {
> -	case PLATFORM_PROFILE_LOW_POWER:
> -		ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_POWERSAVE);
> -		if (ret)
> -			return ret;
> -		break;
> -	case PLATFORM_PROFILE_BALANCED:
> -		ret = amd_pstate_set_epp(policy,
> -					 amd_pstate_get_balanced_epp(policy));
> -		if (ret)
> -			return ret;
> -		break;
> -	case PLATFORM_PROFILE_PERFORMANCE:
> -		ret = amd_pstate_set_epp(policy, AMD_CPPC_EPP_PERFORMANCE);
> -		if (ret)
> -			return ret;
> -		break;
> -	default:
> -		pr_err("Unknown Platform Profile %d\n", profile);
> -		return -EOPNOTSUPP;
> -	}
> +	ret = amd_pstate_get_epp_from_platform_profile(policy, profile);
> +	if (ret < 0)
> +		return ret;
> +
> +	epp = (u8)ret;
> +	ret = amd_pstate_set_epp(policy, epp);
> +	if (ret)
> +		return ret;
>   
>   	cpudata->current_profile = profile;
>   
> @@ -1259,20 +1265,11 @@ static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
>   	int ret;
>   	u8 epp;
>   
> -	switch (cpudata->current_profile) {
> -	case PLATFORM_PROFILE_PERFORMANCE:
> -		epp = AMD_CPPC_EPP_PERFORMANCE;
> -		break;
> -	case PLATFORM_PROFILE_LOW_POWER:
> -		epp = AMD_CPPC_EPP_POWERSAVE;
> -		break;
> -	case PLATFORM_PROFILE_BALANCED:
> -		epp = amd_pstate_get_balanced_epp(policy);
> -		break;
> -	default:
> -		pr_err("Unknown Platform Profile %d\n", cpudata->current_profile);
> -		return -EOPNOTSUPP;
> -	}
> +	ret = amd_pstate_get_epp_from_platform_profile(policy, cpudata->current_profile);
> +	if (ret < 0)
> +		return ret;
> +
> +	epp = (u8)ret;
>   	ret = amd_pstate_set_epp(policy, epp);
>   	if (ret)
>   		return ret;


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 2/6] cpufreq/amd-pstate: Add dynamic EPP as an "energy_performance_preference" mode
  2026-06-30 18:59 ` [RFC PATCH 2/6] cpufreq/amd-pstate: Add dynamic EPP as an "energy_performance_preference" mode K Prateek Nayak
@ 2026-07-01 21:33   ` Mario Limonciello
  0 siblings, 0 replies; 12+ messages in thread
From: Mario Limonciello @ 2026-07-01 21:33 UTC (permalink / raw)
  To: K Prateek Nayak, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, linux-pm, linux-doc, linux-kernel



On 6/30/26 13:59, K Prateek Nayak wrote:
> Conver the global "dynamic_epp" toggle into a per-CPU

Convert

> "energy_performance_preference" mode "dynamic" that allows toggling the
> functionality of "dynamic_epp" at a per-CPU level.
> 
> Instead of being a system-wide toggle, users can opt into the
> functionality of dynamic EPP on a per-CPU basis by switching to the
> powersave governor and selecting the "dynamic" mode from the available
> performance preferences.
> 
> Unlike the previous implementation that had to check for driver mode
> before toggling on the functionality, block writes to certain sysfs
> files, potentially disallow policy change, etc. the per-CPU toggle fits
> naturally into the intended design and provides more granular control to
> the user.

No real concerns here, just a few small nits.

> 
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
> ---
>   drivers/cpufreq/amd-pstate.c | 90 +++++++++++++++++++++++++++++++-----
>   1 file changed, 79 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 1893b0054a6a..c7eec6b96dcc 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -106,6 +106,7 @@ static struct quirk_entry *quirks;
>    *	3		balance_power
>    *	4		power
>    *	5		custom (for raw EPP values)
> + *	6		dynamic (platform profile driven selection)

I would just say "kernel driven decision".  Right now this was driven by 
platform profile, but the vision for dynamic EPP was that the kernel 
could potentially change EPP values for individual cores on more factors.

>    */
>   enum energy_perf_value_index {
>   	EPP_INDEX_DEFAULT = 0,
> @@ -114,6 +115,7 @@ enum energy_perf_value_index {
>   	EPP_INDEX_BALANCE_POWERSAVE,
>   	EPP_INDEX_POWERSAVE,
>   	EPP_INDEX_CUSTOM,
> +	EPP_INDEX_DYNAMIC,
>   	EPP_INDEX_MAX,
>   };
>   
> @@ -124,6 +126,7 @@ static const char * const energy_perf_strings[] = {
>   	[EPP_INDEX_BALANCE_POWERSAVE] = "balance_power",
>   	[EPP_INDEX_POWERSAVE] = "power",
>   	[EPP_INDEX_CUSTOM] = "custom",
> +	[EPP_INDEX_DYNAMIC] = "dynamic",
>   };
>   static_assert(ARRAY_SIZE(energy_perf_strings) == EPP_INDEX_MAX);
>   
> @@ -134,7 +137,7 @@ static unsigned int epp_values[] = {
>   	[EPP_INDEX_BALANCE_POWERSAVE] = AMD_CPPC_EPP_BALANCE_POWERSAVE,
>   	[EPP_INDEX_POWERSAVE] = AMD_CPPC_EPP_POWERSAVE,
>   };
> -static_assert(ARRAY_SIZE(epp_values) == EPP_INDEX_MAX - 1);
> +static_assert(ARRAY_SIZE(epp_values) == EPP_INDEX_MAX - 2);
>   
>   typedef int (*cppc_mode_transition_fn)(int);
>   
> @@ -1262,6 +1265,7 @@ EXPORT_SYMBOL_GPL(amd_pstate_clear_dynamic_epp);
>   static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
>   {
>   	struct amd_cpudata *cpudata = policy->driver_data;
> +	u64 prev = READ_ONCE(cpudata->cppc_req_cached);
>   	int ret;
>   	u8 epp;
>   
> @@ -1302,6 +1306,9 @@ static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
>   cleanup:
>   	amd_pstate_clear_dynamic_epp(policy);
>   
> +	epp = FIELD_GET(AMD_CPPC_EPP_PERF_MASK, prev);
> +	/* Restore previous EPP if toggling Dynamic EPP failed. */
> +	amd_pstate_set_epp(policy, epp);
>   	return ret;
>   }
>   
> @@ -1372,14 +1379,22 @@ static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy,
>   static ssize_t show_energy_performance_available_preferences(
>   				struct cpufreq_policy *policy, char *buf)
>   {
> -	int offset = 0, i;
>   	struct amd_cpudata *cpudata = policy->driver_data;
> +	int i, max = EPP_INDEX_MAX, offset = 0;
>   
>   	if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
>   		return sysfs_emit_at(buf, offset, "%s\n",
>   				energy_perf_strings[EPP_INDEX_PERFORMANCE]);
>   
> -	for (i = 0; i < ARRAY_SIZE(energy_perf_strings); i++)
> +	/*
> +	 * Do not enumerate "dynamic" option only if disabled during boot.
> +	 * Users can still opt in to dynamic EPP if platform (server) has
> +	 * decided to keep it disabled by default.
> +	 */

As we're keeping it disabled for everyone right now, I think you can 
avoid disambiguating server for now.

> +	if (!dynamic_epp)
> +		max = EPP_INDEX_DYNAMIC;
> +
> +	for (i = 0; i < max; i++)
>   		offset += sysfs_emit_at(buf, offset, "%s ", energy_perf_strings[i]);
>   
>   	offset += sysfs_emit_at(buf, offset, "\n");
> @@ -1395,11 +1410,6 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
>   	bool raw_epp = false;
>   	u8 epp;
>   
> -	if (cpudata->dynamic_epp) {
> -		pr_debug("EPP cannot be set when dynamic EPP is enabled\n");
> -		return -EBUSY;
> -	}
> -
>   	/*
>   	 * if the value matches a number, use that, otherwise see if
>   	 * matches an index in the energy_perf_strings array
> @@ -1410,6 +1420,26 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
>   		ret = sysfs_match_string(energy_perf_strings, buf);
>   		if (ret < 0 || ret == EPP_INDEX_CUSTOM)
>   			return -EINVAL;
> +
> +		if (ret == EPP_INDEX_DYNAMIC) {
> +			/* Dynamic EPP disabled at boot or by platform. */
> +			if (!dynamic_epp)
> +				return -EINVAL;
> +			/*
> +			 * Dynamic EPP was already enabled for this CPU.
> +			 * Nothing to do.
> +			 */
> +			if (cpudata->dynamic_epp)
> +				return count;
> +
> +			cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
> +			ret = amd_pstate_set_dynamic_epp(policy);
> +			if (ret)
> +				return ret;
> +
> +			return count;
> +		}
> +
>   		if (ret)
>   			epp = epp_values[ret];
>   		else
> @@ -1421,6 +1451,13 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
>   		return -EBUSY;
>   	}
>   
> +	/*
> +	 * Dynamic EPP was enabled previously!
> +	 * Switch back to the static EPP mode.
> +	 */
> +	if (cpudata->dynamic_epp)
> +		amd_pstate_clear_dynamic_epp(policy);
> +
>   	ret = amd_pstate_set_epp(policy, epp);
>   	if (ret)
>   		return ret;
> @@ -1438,7 +1475,7 @@ ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *
>   
>   	epp = FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached);
>   
> -	if (cpudata->raw_epp)
> +	if (!cpudata->dynamic_epp && cpudata->raw_epp)
>   		return sysfs_emit(buf, "%u\n", epp);
>   
>   	switch (epp) {
> @@ -1458,6 +1495,9 @@ ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *
>   		return -EINVAL;
>   	}
>   
> +	if (cpudata->dynamic_epp)
> +		return sysfs_emit(buf, "dynamic(profile:%s)\n", energy_perf_strings[preference]);
> +
>   	return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
>   }
>   EXPORT_SYMBOL_GPL(show_energy_performance_preference);
> @@ -1943,10 +1983,14 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
>   		cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
>   	}
>   
> -	if (dynamic_epp)
> +	if (dynamic_epp) {
> +		/* Dynamic EPP is only available with the POWERSAVE policy. */
> +		policy->policy = CPUFREQ_POLICY_POWERSAVE;
>   		ret = amd_pstate_set_dynamic_epp(policy);
> -	else
> +	} else {
>   		ret = amd_pstate_set_epp(policy, cpudata->epp_default_dc);
> +	}
> +
>   	if (ret)
>   		goto free_cpudata1;
>   
> @@ -2018,6 +2062,30 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
>   	if (!policy->cpuinfo.max_freq)
>   		return -ENODEV;
>   
> +	/* Must be a switch between PERFORMANCE and POWERSAVE */
> +	if (cpudata->policy != policy->policy) {
> +		/*
> +		 * Disable dynamic_epp when switching
> +		 * out of CPUFREQ_POLICY_POWERSAVE.
> +		 */
> +		if (cpudata->dynamic_epp) {
> +			WARN_ON_ONCE(cpudata->policy != CPUFREQ_POLICY_POWERSAVE);
> +			amd_pstate_clear_dynamic_epp(policy);
> +		}
> +		/*
> +		 * If dynamic_epp is enabled by default, toggle it on
> +		 * when switching to CPUFREQ_POLICY_POWERSAVE.
> +		 */
> +		if (dynamic_epp) {
> +			WARN_ON_ONCE(policy->policy != CPUFREQ_POLICY_POWERSAVE);
> +
> +			cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
> +			ret = amd_pstate_set_dynamic_epp(policy);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
>   	cpudata->policy = policy->policy;
>   
>   	ret = amd_pstate_epp_update_limit(policy, true);


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 5/6] cpufreq/amd-pstate: Reduce the scope of exported symbols
  2026-06-30 19:03 ` [RFC PATCH 5/6] cpufreq/amd-pstate: Reduce the scope of exported symbols K Prateek Nayak
@ 2026-07-01 21:38   ` Mario Limonciello
  0 siblings, 0 replies; 12+ messages in thread
From: Mario Limonciello @ 2026-07-01 21:38 UTC (permalink / raw)
  To: K Prateek Nayak, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, linux-pm, linux-doc, linux-kernel



On 6/30/26 14:03, K Prateek Nayak wrote:
> Symbols exported by amd-pstate.c are ever only needed for amd-pstate-ut.
> Introduce EXPORT_SYMBOL_FOR_PSTATE_UT() to export these symbols
> selectively to "amd-pstate-ut" namespace as opposed to all GPL modules.
> 
> No functional changes intended.
> 
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
> ---
>   drivers/cpufreq/amd-pstate.c | 14 +++++++-------
>   drivers/cpufreq/amd-pstate.h |  7 +++++++
>   2 files changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 61f30820d95a..44c03b0be219 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -75,7 +75,7 @@ const char *amd_pstate_get_mode_string(enum amd_pstate_mode mode)
>   		mode = AMD_PSTATE_UNDEFINED;
>   	return amd_pstate_mode_string[mode];
>   }
> -EXPORT_SYMBOL_GPL(amd_pstate_get_mode_string);
> +EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_get_mode_string);
>   
>   struct quirk_entry {
>   	u32 nominal_freq;
> @@ -1266,7 +1266,7 @@ void amd_pstate_clear_dynamic_epp(struct cpufreq_policy *policy)
>   	kfree(cpudata->profile_name);
>   	cpudata->dynamic_epp = false;
>   }
> -EXPORT_SYMBOL_GPL(amd_pstate_clear_dynamic_epp);
> +EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_clear_dynamic_epp);
>   
>   static int amd_pstate_set_dynamic_epp(struct cpufreq_policy *policy)
>   {
> @@ -1472,7 +1472,7 @@ ssize_t store_energy_performance_preference(struct cpufreq_policy *policy,
>   
>   	return count;
>   }
> -EXPORT_SYMBOL_GPL(store_energy_performance_preference);
> +EXPORT_SYMBOL_FOR_PSTATE_UT(store_energy_performance_preference);
>   
>   ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *buf)
>   {
> @@ -1506,7 +1506,7 @@ ssize_t show_energy_performance_preference(struct cpufreq_policy *policy, char *
>   
>   	return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
>   }
> -EXPORT_SYMBOL_GPL(show_energy_performance_preference);
> +EXPORT_SYMBOL_FOR_PSTATE_UT(show_energy_performance_preference);
>   
>   static ssize_t store_amd_pstate_floor_freq(struct cpufreq_policy *policy,
>   					   const char *buf, size_t count)
> @@ -1606,7 +1606,7 @@ struct freq_attr **amd_pstate_get_current_attrs(void)
>   		return NULL;
>   	return current_pstate_driver->attr;
>   }
> -EXPORT_SYMBOL_GPL(amd_pstate_get_current_attrs);
> +EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_get_current_attrs);
>   
>   static struct freq_attr **get_freq_attrs(void)
>   {
> @@ -1791,7 +1791,7 @@ int amd_pstate_get_status(void)
>   {
>   	return cppc_state;
>   }
> -EXPORT_SYMBOL_GPL(amd_pstate_get_status);
> +EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_get_status);
>   
>   int amd_pstate_update_status(const char *buf, size_t size)
>   {
> @@ -1811,7 +1811,7 @@ int amd_pstate_update_status(const char *buf, size_t size)
>   
>   	return 0;
>   }
> -EXPORT_SYMBOL_GPL(amd_pstate_update_status);
> +EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_update_status);
>   
>   static ssize_t status_show(struct device *dev,
>   			   struct device_attribute *attr, char *buf)
> diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
> index 23e8baa05849..edd697a5e29f 100644
> --- a/drivers/cpufreq/amd-pstate.h
> +++ b/drivers/cpufreq/amd-pstate.h
> @@ -11,6 +11,13 @@
>   #include <linux/pm_qos.h>
>   #include <linux/platform_profile.h>
>   
> +#if IS_MODULE(CONFIG_X86_AMD_PSTATE_UT)
> +#define EXPORT_SYMBOL_FOR_PSTATE_UT(symbol) \
> +	EXPORT_SYMBOL_FOR_MODULES(symbol, "amd-pstate-ut")
> +#else
> +#define EXPORT_SYMBOL_FOR_PSTATE_UT(symbol)
> +#endif
> +
>   /*********************************************************************
>    *                        AMD P-state INTERFACE                       *
>    *********************************************************************/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 3/6] cpufreq/amd-pstate: Repurpose "amd_dynamic_epp" cmdline and corresponding sysfs
  2026-06-30 18:59 ` [RFC PATCH 3/6] cpufreq/amd-pstate: Repurpose "amd_dynamic_epp" cmdline and corresponding sysfs K Prateek Nayak
@ 2026-07-01 21:40   ` Mario Limonciello
  0 siblings, 0 replies; 12+ messages in thread
From: Mario Limonciello @ 2026-07-01 21:40 UTC (permalink / raw)
  To: K Prateek Nayak, Rafael J. Wysocki, Viresh Kumar, Huang Rui
  Cc: Perry Yuan, linux-pm, linux-doc, linux-kernel



On 6/30/26 13:59, K Prateek Nayak wrote:
> Since dynamic_epp has been converted to an
> "energy_performance_preference", toggling the feature via the sysfs file
> is now redundant.
> 
> Repurpose "amd_dynamic_epp=enable" command line to opt into dynamic EPP
> by default when the active driver is loaded, or switched into. The
> "disable" counterpart will "dynamic" option out of
> "energyy_performance_preference" to ensure dynamic EPP feature can never
> be toggled.
> 
> Use a tri-state enum to differentiate if the user has supplied a command
> line parameter or not to enable the feature by default vs keeping the
> current defaults as is and allowing users to toggle it later via the
> "dynamic" option in "energy_performance_preference" selection.
> 
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>

Honestly - I have to question if we even want to have the kernel command 
line option anymore.  If userspace can easily opt in and out as in this 
series, do we still need a kernel command line for default policy?

I'm of the opinion rip it out, less to maintain.

> ---
>   drivers/cpufreq/amd-pstate.c | 48 +++++++++---------------------------
>   1 file changed, 12 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index c7eec6b96dcc..61f30820d95a 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -82,12 +82,18 @@ struct quirk_entry {
>   	u32 lowest_freq;
>   };
>   
> +enum dynamic_epp_state {
> +	DYNAMIC_EPP_USER_TOGGLE = -1,	/* User can toggle dynamic EPP. (Default) */
> +	DYNAMIC_EPP_DISABLED,		/* Dynamic EPP disabled from command line. */
> +	DYNAMIC_EPP_DEFAULT_ENABLED,	/* Dynamic EPP enabled from command line. */
> +};
> +
> +static enum dynamic_epp_state dynamic_epp = DYNAMIC_EPP_USER_TOGGLE;
>   static struct cpufreq_driver *current_pstate_driver;
>   static struct cpufreq_driver amd_pstate_driver;
>   static struct cpufreq_driver amd_pstate_epp_driver;
>   static int cppc_state = AMD_PSTATE_UNDEFINED;
>   static bool amd_pstate_prefcore = true;
> -static bool dynamic_epp;
>   static struct quirk_entry *quirks;
>   
>   /*
> @@ -1839,39 +1845,9 @@ static ssize_t dynamic_epp_show(struct device *dev,
>   	return sysfs_emit(buf, "%s\n", str_enabled_disabled(dynamic_epp));
>   }
>   
> -static ssize_t dynamic_epp_store(struct device *a, struct device_attribute *b,
> -				 const char *buf, size_t count)
> -{
> -	bool enabled;
> -	int ret;
> -
> -	ret = kstrtobool(buf, &enabled);
> -	if (ret)
> -		return ret;
> -
> -	guard(mutex)(&amd_pstate_driver_lock);
> -
> -	if (cppc_state != AMD_PSTATE_ACTIVE) {
> -		pr_debug("dynamic_epp can only be toggled in active mode\n");
> -		return -EINVAL;
> -	}
> -
> -	/* Nothing to do */
> -	if (dynamic_epp == enabled)
> -		return count;
> -
> -	/* reinitialize with desired dynamic EPP value */
> -	dynamic_epp = enabled;
> -	ret = amd_pstate_change_driver_mode(cppc_state);
> -	if (ret)
> -		dynamic_epp = false;
> -
> -	return ret ? ret : count;
> -}
> -
>   static DEVICE_ATTR_RW(status);
>   static DEVICE_ATTR_RO(prefcore);
> -static DEVICE_ATTR_RW(dynamic_epp);
> +static DEVICE_ATTR_RO(dynamic_epp);
>   
>   static struct attribute *pstate_global_attributes[] = {
>   	&dev_attr_status.attr,
> @@ -1983,7 +1959,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
>   		cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
>   	}
>   
> -	if (dynamic_epp) {
> +	if (dynamic_epp == DYNAMIC_EPP_DEFAULT_ENABLED) {
>   		/* Dynamic EPP is only available with the POWERSAVE policy. */
>   		policy->policy = CPUFREQ_POLICY_POWERSAVE;
>   		ret = amd_pstate_set_dynamic_epp(policy);
> @@ -2076,7 +2052,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
>   		 * If dynamic_epp is enabled by default, toggle it on
>   		 * when switching to CPUFREQ_POLICY_POWERSAVE.
>   		 */
> -		if (dynamic_epp) {
> +		if (dynamic_epp == DYNAMIC_EPP_DEFAULT_ENABLED) {
>   			WARN_ON_ONCE(policy->policy != CPUFREQ_POLICY_POWERSAVE);
>   
>   			cpudata->current_profile = PLATFORM_PROFILE_BALANCED;
> @@ -2410,9 +2386,9 @@ static int __init amd_prefcore_param(char *str)
>   static int __init amd_dynamic_epp_param(char *str)
>   {
>   	if (!strcmp(str, "disable"))
> -		dynamic_epp = false;
> +		dynamic_epp = DYNAMIC_EPP_DISABLED;
>   	if (!strcmp(str, "enable"))
> -		dynamic_epp = true;
> +		dynamic_epp = DYNAMIC_EPP_DEFAULT_ENABLED;
>   
>   	return 0;
>   }


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-07-01 21:40 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30 18:58 [RFC PATCH 0/6] cpufreq/amd-pstate: Rework dynamic_epp as an energy_performance_preference mode K Prateek Nayak
2026-06-30 18:58 ` [RFC PATCH 1/6] cpufreq/amd-pstate: Extract platform profile to EPP conversion into a helper K Prateek Nayak
2026-07-01 21:31   ` Mario Limonciello
2026-06-30 18:59 ` [RFC PATCH 2/6] cpufreq/amd-pstate: Add dynamic EPP as an "energy_performance_preference" mode K Prateek Nayak
2026-07-01 21:33   ` Mario Limonciello
2026-06-30 18:59 ` [RFC PATCH 3/6] cpufreq/amd-pstate: Repurpose "amd_dynamic_epp" cmdline and corresponding sysfs K Prateek Nayak
2026-07-01 21:40   ` Mario Limonciello
2026-06-30 18:59 ` [RFC PATCH 4/6] Documentation/amd-pstate: Update dynamic_epp documentation with new behavior K Prateek Nayak
2026-06-30 19:03 ` K Prateek Nayak
2026-06-30 19:03 ` [RFC PATCH 5/6] cpufreq/amd-pstate: Reduce the scope of exported symbols K Prateek Nayak
2026-07-01 21:38   ` Mario Limonciello
2026-06-30 19:03 ` [RFC PATCH 6/6] cpufreq/amd-pstate-ut: Add unit test for "dynamic" EPP mode K Prateek Nayak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox