Linux Power Management development
 help / color / mirror / Atom feed
* [PATCH 0/3] Zen6 client CPPC
@ 2026-08-31 19:44 Mario Limonciello
  2026-08-31 19:44 ` [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling Mario Limonciello
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Mario Limonciello @ 2026-08-31 19:44 UTC (permalink / raw)
  To: Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, K Prateek Nayak, x86,
	Vishal Badole, Mario Limonciello

Zen6 client platforms use CPPC differently than previous platforms
and knowing maximum frequency for a core type is needed for capacity
calculations.

Newer versions of the ACPI will introduce a proper interface
for getting this information, but for now hardcode values so that
these systems perform as intended and to unblock future scheduler
work while we continue to wait.

Mario Limonciello (3):
  ACPI: CPPC: Refactor boost ratio handling
  cpufreq/acpi-cpufreq: Use amd_get_boost_ratio()
  cpufreq/amd-pstate: Get Highest Freq for a CPU

 arch/x86/kernel/acpi/cppc.c    | 174 ++++++++++++++++++++++-----------
 drivers/cpufreq/acpi-cpufreq.c |  17 ++--
 drivers/cpufreq/amd-pstate.c   |  22 +++--
 include/acpi/cppc_acpi.h       |  14 ++-
 4 files changed, 154 insertions(+), 73 deletions(-)

-- 
2.43.0


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

* [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling
  2026-08-31 19:44 [PATCH 0/3] Zen6 client CPPC Mario Limonciello
@ 2026-08-31 19:44 ` Mario Limonciello
  2026-09-01  4:41   ` K Prateek Nayak
  2026-09-01  9:31   ` K Prateek Nayak
  2026-08-31 19:44 ` [PATCH 2/3] cpufreq/acpi-cpufreq: Use amd_get_boost_ratio() Mario Limonciello
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Mario Limonciello @ 2026-08-31 19:44 UTC (permalink / raw)
  To: Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, K Prateek Nayak, x86,
	Vishal Badole, Mario Limonciello

Rename amd_get_boost_ratio_numerator() to amd_get_effective_highest_perf()
to better reflect that it returns the effective highest performance value
for a CPU, accounting for preferred cores and heterogeneous topologies.

Add a new helper amd_get_boost_ratio() for doing both for boost
ratio calculations and update callers to use it.

This refactoring is needed because on some AMD systems (Zen6+),
the boost ratio should be calculated from frequency values rather than
performance values.

The frequency values will eventually come from the BIOS, but for now
use some hardcoded values for Zen6 platforms.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 arch/x86/kernel/acpi/cppc.c    | 174 ++++++++++++++++++++++-----------
 drivers/cpufreq/acpi-cpufreq.c |   5 +-
 drivers/cpufreq/amd-pstate.c   |  14 ++-
 include/acpi/cppc_acpi.h       |  14 ++-
 4 files changed, 142 insertions(+), 65 deletions(-)

diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
index bbade0da5130f..78b32bc93e603 100644
--- a/arch/x86/kernel/acpi/cppc.c
+++ b/arch/x86/kernel/acpi/cppc.c
@@ -10,6 +10,7 @@
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/topology.h>
+#include <asm/cpu_device_id.h>
 
 #define CPPC_HIGHEST_PERF_PERFORMANCE	196
 #define CPPC_HIGHEST_PERF_PREFCORE	166
@@ -81,31 +82,18 @@ int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
 
 static void amd_set_max_freq_ratio(void)
 {
-	struct cppc_perf_caps perf_caps;
-	u64 numerator, nominal_perf;
+	u64 numerator, denominator;
 	u64 perf_ratio;
 	int rc;
 
-	rc = cppc_get_perf_caps(0, &perf_caps);
+	rc = amd_get_boost_ratio(0, &numerator, &denominator);
 	if (rc) {
-		pr_debug("Could not retrieve perf counters (%d)\n", rc);
-		return;
-	}
-
-	rc = amd_get_boost_ratio_numerator(0, &numerator);
-	if (rc) {
-		pr_debug("Could not retrieve highest performance (%d)\n", rc);
-		return;
-	}
-	nominal_perf = perf_caps.nominal_perf;
-
-	if (!nominal_perf) {
-		pr_debug("Could not retrieve nominal performance\n");
+		pr_debug("Could not retrieve boost ratio (%d)\n", rc);
 		return;
 	}
 
 	/* midpoint between max_boost and max_P */
-	perf_ratio = (div_u64(numerator * SCHED_CAPACITY_SCALE, nominal_perf) + SCHED_CAPACITY_SCALE) >> 1;
+	perf_ratio = (div_u64(numerator * SCHED_CAPACITY_SCALE, denominator) + SCHED_CAPACITY_SCALE) >> 1;
 
 	freq_invariance_set_perf_ratio(perf_ratio, false);
 }
@@ -225,35 +213,30 @@ int amd_detect_prefcore(bool *detected)
 EXPORT_SYMBOL_GPL(amd_detect_prefcore);
 
 /**
- * amd_get_boost_ratio_numerator: Get the numerator to use for boost ratio calculation
- * @cpu: CPU to get numerator for.
- * @numerator: Output variable for numerator.
+ * amd_get_effective_highest_perf: Get the effective highest performance value
+ * @cpu: CPU to get highest performance for.
  *
- * Determine the numerator to use for calculating the boost ratio on
- * a CPU. On systems that support preferred cores, this will be a hardcoded
- * value. On other systems this will the highest performance register value.
+ * Get the effective highest performance value for a CPU, accounting for
+ * preferred cores and heterogeneous topologies. On systems with preferred
+ * cores, this may be a hardcoded value. On heterogeneous systems, this
+ * may be a per-CPU value. On other systems, this is the shared highest
+ * performance value.
  *
- * If booting the system with amd-pstate enabled but preferred cores disabled then
- * the correct boost numerator will be returned to match hardware capabilities
- * even if the preferred cores scheduling hints are not enabled.
- *
- * Return: 0 for success, negative error code otherwise.
+ * Return: Effective highest performance value, or negative error code.
  */
-int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
+int amd_get_effective_highest_perf(unsigned int cpu)
 {
 	bool prefcore;
 	int ret;
 	u32 tmp;
 
 	ret = amd_detect_prefcore(&prefcore);
-	if (ret)
+	if (ret < 0)
 		return ret;
 
 	/* without preferred cores, return the highest perf register value */
-	if (!prefcore) {
-		*numerator = boost_numerator;
-		return 0;
-	}
+	if (!prefcore)
+		return boost_numerator;
 
 	/*
 	 * For AMD CPUs with Family ID 19H and Model ID range 0x70 to 0x7f,
@@ -263,8 +246,7 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
 	if (cpu_feature_enabled(X86_FEATURE_ZEN4)) {
 		switch (boot_cpu_data.x86_model) {
 		case 0x70 ... 0x7f:
-			*numerator = CPPC_HIGHEST_PERF_PERFORMANCE;
-			return 0;
+			return CPPC_HIGHEST_PERF_PERFORMANCE;
 		default:
 			break;
 		}
@@ -272,28 +254,108 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
 
 	/* detect if running on heterogeneous design */
 	if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) {
-		switch (cpu_data(cpu).topo.cpu_type) {
-		case TOPO_CPU_TYPE_UNKNOWN:
-		case TOPO_CPU_TYPE_ANY:
-			pr_warn("Undefined core type found for cpu %d\n", cpu);
-			break;
-		case TOPO_CPU_TYPE_PERFORMANCE:
-			/* use the max scale for performance cores */
-			*numerator = CPPC_HIGHEST_PERF_PERFORMANCE;
-			return 0;
-		case TOPO_CPU_TYPE_LOW_POWER:
-		case TOPO_CPU_TYPE_EFFICIENCY:
-			/* use the highest perf value for efficiency and low-power cores */
-			ret = amd_get_highest_perf(cpu, &tmp);
-			if (ret)
-				return ret;
-			*numerator = tmp;
-			return 0;
-		}
+		if (cpu_feature_enabled(X86_FEATURE_ZEN5) &&
+		    cpu_data(cpu).topo.cpu_type == TOPO_CPU_TYPE_PERFORMANCE)
+			return CPPC_HIGHEST_PERF_PERFORMANCE;
+
+		/* Zen 5 efficiency, and Zen 6+ */
+		ret = amd_get_highest_perf(cpu, &tmp);
+		if (ret < 0)
+			return ret;
+
+		return tmp;
 	}
 
-	*numerator = CPPC_HIGHEST_PERF_PREFCORE;
+	return CPPC_HIGHEST_PERF_PREFCORE;
+}
+EXPORT_SYMBOL_GPL(amd_get_effective_highest_perf);
+
+struct amd_max_freq {
+	u32 performance;
+	u32 efficiency;
+	u32 low_power;
+};
+
+static const struct amd_max_freq max_freq_zen6_client __initconst = {
+	.performance = 5025,
+	.efficiency = 3524,
+	.low_power = 2399,
+};
+
+static const struct x86_cpu_id amd_zen6_client_ids[] __initconst = {
+	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x80, &max_freq_zen6_client),
+	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x81, &max_freq_zen6_client),
+	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x84, &max_freq_zen6_client),
+	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x85, &max_freq_zen6_client),
+	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0xe0, &max_freq_zen6_client),
+	{}
+};
+
+int amd_get_max_frequency(unsigned int cpu)
+{
+	enum x86_topology_cpu_type type = cpu_data(cpu).topo.cpu_type;
+	const struct x86_cpu_id *id = x86_match_cpu(amd_zen6_client_ids);
+	const struct amd_max_freq *max_freq;
+
+	if (!id)
+		return -ENODEV;
+
+	max_freq = (const struct amd_max_freq *)id->driver_data;
+
+	switch (type) {
+	case TOPO_CPU_TYPE_PERFORMANCE:
+		return max_freq->performance;
+	case TOPO_CPU_TYPE_EFFICIENCY:
+		return max_freq->efficiency;
+	case TOPO_CPU_TYPE_LOW_POWER:
+		return max_freq->low_power;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(amd_get_max_frequency);
+
+/**
+ * amd_get_boost_ratio: Get numerator and denominator for boost ratio
+ * @cpu: CPU to get the boost ratio for.
+ * @numerator: Output variable for numerator.
+ * @denominator: Output variable for denominator.
+ *
+ * Get the numerator and denominator for calculating the boost ratio.
+ *
+ * Return: 0 for success, negative error code otherwise.
+ */
+int amd_get_boost_ratio(unsigned int cpu, u64 *numerator, u64 *denominator)
+{
+	struct cppc_perf_caps perf_caps;
+	int max_frequency;
+	int ret;
+
+	ret = cppc_get_perf_caps(cpu, &perf_caps);
+	if (ret)
+		return ret;
+
+	max_frequency = amd_get_max_frequency(cpu);
+	/* Use frequency values if available */
+	if (max_frequency > 0 && perf_caps.nominal_freq) {
+		*numerator = max_frequency;
+		*denominator = perf_caps.nominal_freq;
+		return 0;
+	}
+
+	/* Fall back to performance values */
+	ret = amd_get_effective_highest_perf(cpu);
+	if (ret < 0)
+		return ret;
+
+	*numerator = ret;
+
+	*denominator = perf_caps.nominal_perf;
+	if (!*denominator)
+		return -EINVAL;
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(amd_get_boost_ratio_numerator);
+EXPORT_SYMBOL_GPL(amd_get_boost_ratio);
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 10ea6035f4ad6..523ee1a06ef8a 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -640,12 +640,13 @@ static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq)
 	}
 
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
-		ret = amd_get_boost_ratio_numerator(cpu, &highest_perf);
-		if (ret) {
+		ret = amd_get_effective_highest_perf(cpu);
+		if (ret < 0) {
 			pr_debug("CPU%d: Unable to get boost ratio numerator (%d)\n",
 				 cpu, ret);
 			return 0;
 		}
+		highest_perf = ret;
 	} else {
 		highest_perf = perf_caps.highest_perf;
 	}
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index d2b4a8eba3052..9fb1d7150c356 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -584,11 +584,13 @@ static int msr_init_perf(struct amd_cpudata *cpudata)
 	if (ret)
 		return ret;
 
-	ret = amd_get_boost_ratio_numerator(cpudata->cpu, &numerator);
-	if (ret)
+	ret = amd_get_effective_highest_perf(cpudata->cpu);
+	if (ret < 0)
 		return ret;
 
-	ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &cppc_req);
+	numerator = ret;
+
+	ret = rdmsrq_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &cppc_req);
 	if (ret)
 		return ret;
 
@@ -619,10 +621,12 @@ static int shmem_init_perf(struct amd_cpudata *cpudata)
 	if (ret)
 		return ret;
 
-	ret = amd_get_boost_ratio_numerator(cpudata->cpu, &numerator);
-	if (ret)
+	ret = amd_get_effective_highest_perf(cpudata->cpu);
+	if (ret < 0)
 		return ret;
 
+	numerator = ret;
+
 	perf.highest_perf = numerator;
 	perf.max_limit_perf = numerator;
 	perf.min_limit_perf = cppc_perf.lowest_perf;
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index 94a6277edab27..4c0b11a718e38 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -192,7 +192,9 @@ extern int cppc_set_auto_sel(int cpu, bool enable);
 extern int cppc_get_perf_limited(int cpu, u64 *perf_limited);
 extern int cppc_set_perf_limited(int cpu, u64 bits_to_clear);
 extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf);
-extern int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator);
+extern int amd_get_effective_highest_perf(unsigned int cpu);
+extern int amd_get_max_frequency(unsigned int cpu);
+extern int amd_get_boost_ratio(unsigned int cpu, u64 *numerator, u64 *denominator);
 extern int amd_detect_prefcore(bool *detected);
 #else /* !CONFIG_ACPI_CPPC_LIB */
 static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
@@ -305,7 +307,15 @@ static inline int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf)
 {
 	return -ENODEV;
 }
-static inline int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
+static inline int amd_get_effective_highest_perf(unsigned int cpu)
+{
+	return -EOPNOTSUPP;
+}
+static inline int amd_get_max_frequency(unsigned int cpu)
+{
+	return 0;
+}
+static inline int amd_get_boost_ratio(unsigned int cpu, u64 *numerator, u64 *denominator)
 {
 	return -EOPNOTSUPP;
 }
-- 
2.43.0


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

* [PATCH 2/3] cpufreq/acpi-cpufreq: Use amd_get_boost_ratio()
  2026-08-31 19:44 [PATCH 0/3] Zen6 client CPPC Mario Limonciello
  2026-08-31 19:44 ` [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling Mario Limonciello
@ 2026-08-31 19:44 ` Mario Limonciello
  2026-08-31 19:44 ` [PATCH 3/3] cpufreq/amd-pstate: Get Highest Freq for a CPU Mario Limonciello
  2026-09-01  9:36 ` [PATCH 0/3] Zen6 client CPPC K Prateek Nayak
  3 siblings, 0 replies; 11+ messages in thread
From: Mario Limonciello @ 2026-08-31 19:44 UTC (permalink / raw)
  To: Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, K Prateek Nayak, x86,
	Vishal Badole, Mario Limonciello

Update get_max_boost_ratio() to use the new amd_get_boost_ratio()
helper function instead of calling amd_get_effective_highest_perf()
directly.

This ensures the boost ratio is calculated correctly on systems where
frequency values should be used instead of performance values.

Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/cpufreq/acpi-cpufreq.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 523ee1a06ef8a..2e74a000cdc74 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -626,7 +626,7 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
 static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq)
 {
 	struct cppc_perf_caps perf_caps;
-	u64 highest_perf, nominal_perf;
+	u64 numerator, denominator;
 	int ret;
 
 	if (acpi_pstate_strict)
@@ -640,33 +640,31 @@ static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq)
 	}
 
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
-		ret = amd_get_effective_highest_perf(cpu);
-		if (ret < 0) {
-			pr_debug("CPU%d: Unable to get boost ratio numerator (%d)\n",
+		ret = amd_get_boost_ratio(cpu, &numerator, &denominator);
+		if (ret) {
+			pr_debug("CPU%d: Unable to get boost ratio (%d)\n",
 				 cpu, ret);
 			return 0;
 		}
-		highest_perf = ret;
 	} else {
-		highest_perf = perf_caps.highest_perf;
+		numerator = perf_caps.highest_perf;
+		denominator = perf_caps.nominal_perf;
 	}
 
-	nominal_perf = perf_caps.nominal_perf;
-
 	if (nominal_freq)
 		*nominal_freq = perf_caps.nominal_freq * 1000;
 
-	if (!highest_perf || !nominal_perf) {
+	if (!numerator || !denominator) {
 		pr_debug("CPU%d: highest or nominal performance missing\n", cpu);
 		return 0;
 	}
 
-	if (highest_perf < nominal_perf) {
+	if (numerator < denominator) {
 		pr_debug("CPU%d: nominal performance above highest\n", cpu);
 		return 0;
 	}
 
-	return div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
+	return div_u64(numerator << SCHED_CAPACITY_SHIFT, denominator);
 }
 
 #else
-- 
2.43.0


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

* [PATCH 3/3] cpufreq/amd-pstate: Get Highest Freq for a CPU
  2026-08-31 19:44 [PATCH 0/3] Zen6 client CPPC Mario Limonciello
  2026-08-31 19:44 ` [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling Mario Limonciello
  2026-08-31 19:44 ` [PATCH 2/3] cpufreq/acpi-cpufreq: Use amd_get_boost_ratio() Mario Limonciello
@ 2026-08-31 19:44 ` Mario Limonciello
  2026-09-01  9:36 ` [PATCH 0/3] Zen6 client CPPC K Prateek Nayak
  3 siblings, 0 replies; 11+ messages in thread
From: Mario Limonciello @ 2026-08-31 19:44 UTC (permalink / raw)
  To: Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, K Prateek Nayak, x86,
	Vishal Badole, Mario Limonciello

If the highest frequency is known for a CPU, use this instead of
trying to calculate by linear interpolation.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/cpufreq/amd-pstate.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 9fb1d7150c356..a71f82c93c345 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1107,6 +1107,7 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
 	u32 min_freq, max_freq, nominal_freq, lowest_nonlinear_freq;
 	struct cppc_perf_caps cppc_perf;
 	union perf_cached perf;
+	int max_frequency;
 	int ret;
 
 	ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
@@ -1131,8 +1132,13 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
 
 	WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
 
+	/* max freq came from BIOS or quirk */
+	max_frequency = amd_get_max_frequency(cpudata->cpu);
+	if (max_frequency > 0)
+		max_freq = max_frequency * 1000;
 	/* max_freq is calculated according to (nominal_freq * highest_perf)/nominal_perf */
-	max_freq = perf_to_freq(perf, nominal_freq, perf.highest_perf);
+	else
+		max_freq = perf_to_freq(perf, nominal_freq, perf.highest_perf);
 	WRITE_ONCE(cpudata->max_freq, max_freq);
 
 	lowest_nonlinear_freq = perf_to_freq(perf, nominal_freq, perf.lowest_nonlinear_perf);
-- 
2.43.0


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

* Re: [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling
  2026-08-31 19:44 ` [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling Mario Limonciello
@ 2026-09-01  4:41   ` K Prateek Nayak
  2026-09-01 15:26     ` Mario Limonciello
  2026-09-01  9:31   ` K Prateek Nayak
  1 sibling, 1 reply; 11+ messages in thread
From: K Prateek Nayak @ 2026-09-01  4:41 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, x86, Vishal Badole

Hello Mario,

On 9/1/2026 1:14 AM, Mario Limonciello wrote:
> +static const struct amd_max_freq max_freq_zen6_client __initconst = {
> +	.performance = 5025,
> +	.efficiency = 3524,
> +	.low_power = 2399,
> +};
> +
> +static const struct x86_cpu_id amd_zen6_client_ids[] __initconst = {
> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x80, &max_freq_zen6_client),
> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x81, &max_freq_zen6_client),
> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x84, &max_freq_zen6_client),
> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x85, &max_freq_zen6_client),
> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0xe0, &max_freq_zen6_client),
> +	{}
> +};

So I see:

  WARNING: modpost: vmlinux: section mismatch in reference: amd_get_max_frequency+0x27 (section: .text) -> amd_zen6_client_ids (section: .init.rodata)

Since amd_get_boost_ratio() can be called post init too, I think
dropping the __initconst annotation makes sense for these constants
otherwise we may have issues after initmem is freed.

-- 
Thanks and Regards,
Prateek


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

* Re: [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling
  2026-08-31 19:44 ` [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling Mario Limonciello
  2026-09-01  4:41   ` K Prateek Nayak
@ 2026-09-01  9:31   ` K Prateek Nayak
  2026-09-01 15:28     ` Mario Limonciello
  1 sibling, 1 reply; 11+ messages in thread
From: K Prateek Nayak @ 2026-09-01  9:31 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, x86, Vishal Badole

On 9/1/2026 1:14 AM, Mario Limonciello wrote:
> +int amd_get_max_frequency(unsigned int cpu)
> +{
> +	enum x86_topology_cpu_type type = cpu_data(cpu).topo.cpu_type;
> +	const struct x86_cpu_id *id = x86_match_cpu(amd_zen6_client_ids);
> +	const struct amd_max_freq *max_freq;
> +
> +	if (!id)
> +		return -ENODEV;
> +
> +	max_freq = (const struct amd_max_freq *)id->driver_data;
> +
> +	switch (type) {
> +	case TOPO_CPU_TYPE_PERFORMANCE:
> +		return max_freq->performance;
> +	case TOPO_CPU_TYPE_EFFICIENCY:
> +		return max_freq->efficiency;
> +	case TOPO_CPU_TYPE_LOW_POWER:
> +		return max_freq->low_power;
> +	default:
> +		break;
> +	}
> +
> +	return -EINVAL;

nit. Since we don't really propagate the error codes returned
by amd_get_max_frequency(), maybe we can return 0 instead of
-ENODEV, -EINVAL and the callers can simply do:

    max_freq = amd_get_max_frequency(cpu);
    if (!max_freq)
         max_freq = /* Fallback */;

similar to get_max_boost_ratio() pattern. No strong feelings
either way.

> +}
> +EXPORT_SYMBOL_GPL(amd_get_max_frequency);
-- 
Thanks and Regards,
Prateek


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

* Re: [PATCH 0/3] Zen6 client CPPC
  2026-08-31 19:44 [PATCH 0/3] Zen6 client CPPC Mario Limonciello
                   ` (2 preceding siblings ...)
  2026-08-31 19:44 ` [PATCH 3/3] cpufreq/amd-pstate: Get Highest Freq for a CPU Mario Limonciello
@ 2026-09-01  9:36 ` K Prateek Nayak
  3 siblings, 0 replies; 11+ messages in thread
From: K Prateek Nayak @ 2026-09-01  9:36 UTC (permalink / raw)
  To: Mario Limonciello, Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, x86, Vishal Badole

Hello Mario,

On 9/1/2026 1:14 AM, Mario Limonciello wrote:
> Zen6 client platforms use CPPC differently than previous platforms
> and knowing maximum frequency for a core type is needed for capacity
> calculations.
> 
> Newer versions of the ACPI will introduce a proper interface
> for getting this information, but for now hardcode values so that
> these systems perform as intended and to unblock future scheduler
> work while we continue to wait.

I did some sanity testing on couple of servers and everything looks
good apart from that one section mismatch warning. Feel free to
include:

Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>

> 
> Mario Limonciello (3):
>   ACPI: CPPC: Refactor boost ratio handling
>   cpufreq/acpi-cpufreq: Use amd_get_boost_ratio()
>   cpufreq/amd-pstate: Get Highest Freq for a CPU
> 
>  arch/x86/kernel/acpi/cppc.c    | 174 ++++++++++++++++++++++-----------
>  drivers/cpufreq/acpi-cpufreq.c |  17 ++--
>  drivers/cpufreq/amd-pstate.c   |  22 +++--
>  include/acpi/cppc_acpi.h       |  14 ++-
>  4 files changed, 154 insertions(+), 73 deletions(-)
> 

-- 
Thanks and Regards,
Prateek


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

* Re: [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling
  2026-09-01  4:41   ` K Prateek Nayak
@ 2026-09-01 15:26     ` Mario Limonciello
  0 siblings, 0 replies; 11+ messages in thread
From: Mario Limonciello @ 2026-09-01 15:26 UTC (permalink / raw)
  To: K Prateek Nayak, Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, x86, Vishal Badole



On 8/31/26 23:41, K Prateek Nayak wrote:
> Hello Mario,
> 
> On 9/1/2026 1:14 AM, Mario Limonciello wrote:
>> +static const struct amd_max_freq max_freq_zen6_client __initconst = {
>> +	.performance = 5025,
>> +	.efficiency = 3524,
>> +	.low_power = 2399,
>> +};
>> +
>> +static const struct x86_cpu_id amd_zen6_client_ids[] __initconst = {
>> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x80, &max_freq_zen6_client),
>> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x81, &max_freq_zen6_client),
>> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x84, &max_freq_zen6_client),
>> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0x85, &max_freq_zen6_client),
>> +	X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x1A, 0xe0, &max_freq_zen6_client),
>> +	{}
>> +};
> 
> So I see:
> 
>    WARNING: modpost: vmlinux: section mismatch in reference: amd_get_max_frequency+0x27 (section: .text) -> amd_zen6_client_ids (section: .init.rodata)
> 
> Since amd_get_boost_ratio() can be called post init too, I think
> dropping the __initconst annotation makes sense for these constants
> otherwise we may have issues after initmem is freed.
> 

Thanks, will get this fixed.  I didn't catch it because I usually step 
out during my kernel builds and it didn't make enough noise to stop the 
build :P.

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

* Re: [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling
  2026-09-01  9:31   ` K Prateek Nayak
@ 2026-09-01 15:28     ` Mario Limonciello
  2026-09-01 16:34       ` Rafael J. Wysocki (Intel)
  0 siblings, 1 reply; 11+ messages in thread
From: Mario Limonciello @ 2026-09-01 15:28 UTC (permalink / raw)
  To: K Prateek Nayak, Rafael J . Wysocki
  Cc: linux-acpi, linux-kernel, linux-pm, x86, Vishal Badole



On 9/1/26 04:31, K Prateek Nayak wrote:
> On 9/1/2026 1:14 AM, Mario Limonciello wrote:
>> +int amd_get_max_frequency(unsigned int cpu)
>> +{
>> +	enum x86_topology_cpu_type type = cpu_data(cpu).topo.cpu_type;
>> +	const struct x86_cpu_id *id = x86_match_cpu(amd_zen6_client_ids);
>> +	const struct amd_max_freq *max_freq;
>> +
>> +	if (!id)
>> +		return -ENODEV;
>> +
>> +	max_freq = (const struct amd_max_freq *)id->driver_data;
>> +
>> +	switch (type) {
>> +	case TOPO_CPU_TYPE_PERFORMANCE:
>> +		return max_freq->performance;
>> +	case TOPO_CPU_TYPE_EFFICIENCY:
>> +		return max_freq->efficiency;
>> +	case TOPO_CPU_TYPE_LOW_POWER:
>> +		return max_freq->low_power;
>> +	default:
>> +		break;
>> +	}
>> +
>> +	return -EINVAL;
> 
> nit. Since we don't really propagate the error codes returned
> by amd_get_max_frequency(), maybe we can return 0 instead of
> -ENODEV, -EINVAL and the callers can simply do:
> 
>      max_freq = amd_get_max_frequency(cpu);
>      if (!max_freq)
>           max_freq = /* Fallback */;
> 
> similar to get_max_boost_ratio() pattern. No strong feelings
> either way.
> 

OK.  Will adjust for next version.

>> +}
>> +EXPORT_SYMBOL_GPL(amd_get_max_frequency);


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

* Re: [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling
  2026-09-01 15:28     ` Mario Limonciello
@ 2026-09-01 16:34       ` Rafael J. Wysocki (Intel)
  2026-09-01 16:44         ` Mario Limonciello
  0 siblings, 1 reply; 11+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-09-01 16:34 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: K Prateek Nayak, Rafael J . Wysocki, linux-acpi, linux-kernel,
	linux-pm, x86, Vishal Badole

On Tue, Sep 1, 2026 at 5:28 PM Mario Limonciello
<mario.limonciello@amd.com> wrote:
>
>
>
> On 9/1/26 04:31, K Prateek Nayak wrote:
> > On 9/1/2026 1:14 AM, Mario Limonciello wrote:
> >> +int amd_get_max_frequency(unsigned int cpu)
> >> +{
> >> +    enum x86_topology_cpu_type type = cpu_data(cpu).topo.cpu_type;
> >> +    const struct x86_cpu_id *id = x86_match_cpu(amd_zen6_client_ids);
> >> +    const struct amd_max_freq *max_freq;
> >> +
> >> +    if (!id)
> >> +            return -ENODEV;
> >> +
> >> +    max_freq = (const struct amd_max_freq *)id->driver_data;
> >> +
> >> +    switch (type) {
> >> +    case TOPO_CPU_TYPE_PERFORMANCE:
> >> +            return max_freq->performance;
> >> +    case TOPO_CPU_TYPE_EFFICIENCY:
> >> +            return max_freq->efficiency;
> >> +    case TOPO_CPU_TYPE_LOW_POWER:
> >> +            return max_freq->low_power;
> >> +    default:
> >> +            break;
> >> +    }
> >> +
> >> +    return -EINVAL;
> >
> > nit. Since we don't really propagate the error codes returned
> > by amd_get_max_frequency(), maybe we can return 0 instead of
> > -ENODEV, -EINVAL and the callers can simply do:
> >
> >      max_freq = amd_get_max_frequency(cpu);
> >      if (!max_freq)
> >           max_freq = /* Fallback */;
> >
> > similar to get_max_boost_ratio() pattern. No strong feelings
> > either way.
> >
>
> OK.  Will adjust for next version.
>
> >> +}
> >> +EXPORT_SYMBOL_GPL(amd_get_max_frequency);

Please note though that all CPPC-related material is gated on this patch series:

https://lore.kernel.org/linux-acpi/20260830115644.2056983-1-christian.loehle@arm.com/

and there are other multiple series already waiting.

That queue needs to be flushed I'm afraid.

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

* Re: [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling
  2026-09-01 16:34       ` Rafael J. Wysocki (Intel)
@ 2026-09-01 16:44         ` Mario Limonciello
  0 siblings, 0 replies; 11+ messages in thread
From: Mario Limonciello @ 2026-09-01 16:44 UTC (permalink / raw)
  To: Rafael J. Wysocki (Intel)
  Cc: K Prateek Nayak, linux-acpi, linux-kernel, linux-pm, x86,
	Vishal Badole



On 9/1/26 11:34, Rafael J. Wysocki (Intel) wrote:
> On Tue, Sep 1, 2026 at 5:28 PM Mario Limonciello
> <mario.limonciello@amd.com> wrote:
>>
>>
>>
>> On 9/1/26 04:31, K Prateek Nayak wrote:
>>> On 9/1/2026 1:14 AM, Mario Limonciello wrote:
>>>> +int amd_get_max_frequency(unsigned int cpu)
>>>> +{
>>>> +    enum x86_topology_cpu_type type = cpu_data(cpu).topo.cpu_type;
>>>> +    const struct x86_cpu_id *id = x86_match_cpu(amd_zen6_client_ids);
>>>> +    const struct amd_max_freq *max_freq;
>>>> +
>>>> +    if (!id)
>>>> +            return -ENODEV;
>>>> +
>>>> +    max_freq = (const struct amd_max_freq *)id->driver_data;
>>>> +
>>>> +    switch (type) {
>>>> +    case TOPO_CPU_TYPE_PERFORMANCE:
>>>> +            return max_freq->performance;
>>>> +    case TOPO_CPU_TYPE_EFFICIENCY:
>>>> +            return max_freq->efficiency;
>>>> +    case TOPO_CPU_TYPE_LOW_POWER:
>>>> +            return max_freq->low_power;
>>>> +    default:
>>>> +            break;
>>>> +    }
>>>> +
>>>> +    return -EINVAL;
>>>
>>> nit. Since we don't really propagate the error codes returned
>>> by amd_get_max_frequency(), maybe we can return 0 instead of
>>> -ENODEV, -EINVAL and the callers can simply do:
>>>
>>>       max_freq = amd_get_max_frequency(cpu);
>>>       if (!max_freq)
>>>            max_freq = /* Fallback */;
>>>
>>> similar to get_max_boost_ratio() pattern. No strong feelings
>>> either way.
>>>
>>
>> OK.  Will adjust for next version.
>>
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(amd_get_max_frequency);
> 
> Please note though that all CPPC-related material is gated on this patch series:
> 
> https://lore.kernel.org/linux-acpi/20260830115644.2056983-1-christian.loehle@arm.com/
> 
> and there are other multiple series already waiting.
> 
> That queue needs to be flushed I'm afraid.

Thanks, I'll rebase and test on that series.
I was just CC'ed into it today too.

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

end of thread, other threads:[~2026-09-01 16:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31 19:44 [PATCH 0/3] Zen6 client CPPC Mario Limonciello
2026-08-31 19:44 ` [PATCH 1/3] ACPI: CPPC: Refactor boost ratio handling Mario Limonciello
2026-09-01  4:41   ` K Prateek Nayak
2026-09-01 15:26     ` Mario Limonciello
2026-09-01  9:31   ` K Prateek Nayak
2026-09-01 15:28     ` Mario Limonciello
2026-09-01 16:34       ` Rafael J. Wysocki (Intel)
2026-09-01 16:44         ` Mario Limonciello
2026-08-31 19:44 ` [PATCH 2/3] cpufreq/acpi-cpufreq: Use amd_get_boost_ratio() Mario Limonciello
2026-08-31 19:44 ` [PATCH 3/3] cpufreq/amd-pstate: Get Highest Freq for a CPU Mario Limonciello
2026-09-01  9:36 ` [PATCH 0/3] Zen6 client CPPC 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