[PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF

Gautham R. Shenoy posted 12 patches 2 weeks ago
There is a newer version of this series
[PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
Posted by Gautham R. Shenoy 2 weeks ago
Some future AMD processors have feature named "CPPC Performance
Priority" which lets userspace specify different floor performance
levels for different CPUs. The platform firmware takes these different
floor performance levels into consideration while throttling the CPUs
under power/thermal constraints. The presence of this feature is
indicated by bit 16 of the EDX register for CPUID leaf
0x80000007. More details can be found in AMD Publication titled "AMD64
Collaborative Processor Performance Control (CPPC) Performance
Priority" Revision 1.10.

The number of distinct floor performance levels supported on the
platform will be advertised through the bits 32:39 of the
MSR_AMD_CPPC_CAP1. Bits 0:7 of a new MSR MSR_AMD_CPPC_REQ2
(0xc00102b5) will be used to specify the desired floor performance
level for that CPU.

Add support for the aforementioned MSR_AMD_CPPC_REQ2, and macros for
parsing and updating the relevant bits from MSR_AMD_CPPC_CAP1 and
MSR_AMD_CPPC_REQ2.

On boot if the default value of the MSR_AMD_CPPC_REQ2[7:0] (Floor
Perf) is lower than CPPC.lowest_perf, and thus invalid, initialize it
to MSR_AMD_CPPC_CAP1.nominal_perf which is a sane default value.

Save the boot-time floor_perf during amd_pstate_init_floor_perf(). In
a subsequent patch it will be restored in the suspend, offline, and
exit paths, mirroring how bios_min_perf is handled for
MSR_AMD_CPPC_REQ.

Link: https://docs.amd.com/v/u/en-US/69206_1.10_AMD64_CPPC_PUB
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
 arch/x86/include/asm/msr-index.h |  5 ++
 drivers/cpufreq/amd-pstate.c     | 78 +++++++++++++++++++++++++++++++-
 drivers/cpufreq/amd-pstate.h     |  6 +++
 3 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6673601246b3..e126c7fb69cf 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -765,12 +765,14 @@
 #define MSR_AMD_CPPC_CAP2		0xc00102b2
 #define MSR_AMD_CPPC_REQ		0xc00102b3
 #define MSR_AMD_CPPC_STATUS		0xc00102b4
+#define MSR_AMD_CPPC_REQ2		0xc00102b5
 
 /* Masks for use with MSR_AMD_CPPC_CAP1 */
 #define AMD_CPPC_LOWEST_PERF_MASK	GENMASK(7, 0)
 #define AMD_CPPC_LOWNONLIN_PERF_MASK	GENMASK(15, 8)
 #define AMD_CPPC_NOMINAL_PERF_MASK	GENMASK(23, 16)
 #define AMD_CPPC_HIGHEST_PERF_MASK	GENMASK(31, 24)
+#define AMD_CPPC_FLOOR_PERF_CNT_MASK	GENMASK_ULL(39, 32)
 
 /* Masks for use with MSR_AMD_CPPC_REQ */
 #define AMD_CPPC_MAX_PERF_MASK		GENMASK(7, 0)
@@ -778,6 +780,9 @@
 #define AMD_CPPC_DES_PERF_MASK		GENMASK(23, 16)
 #define AMD_CPPC_EPP_PERF_MASK		GENMASK(31, 24)
 
+/* Masks for use with MSR_AMD_CPPC_REQ2 */
+#define AMD_CPPC_FLOOR_PERF_MASK	GENMASK(7, 0)
+
 /* AMD Performance Counter Global Status and Control MSRs */
 #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS	0xc0000300
 #define MSR_AMD64_PERF_CNTR_GLOBAL_CTL		0xc0000301
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 4de2037a414c..53b8173ff183 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -329,6 +329,65 @@ static inline int amd_pstate_set_epp(struct cpufreq_policy *policy, u8 epp)
 	return static_call(amd_pstate_set_epp)(policy, epp);
 }
 
+static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf)
+{
+	struct amd_cpudata *cpudata = policy->driver_data;
+	u64 value, prev;
+	int ret;
+
+	if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
+		return 0;
+
+	value = prev = READ_ONCE(cpudata->cppc_req2_cached);
+	FIELD_MODIFY(AMD_CPPC_FLOOR_PERF_MASK, &value, perf);
+
+	if (value == prev)
+		return 0;
+
+	ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, value);
+	if (ret) {
+		pr_err("failed to set CPPC REQ2 value. Error (%d)\n", ret);
+		return ret;
+	}
+
+	WRITE_ONCE(cpudata->cppc_req2_cached, value);
+
+	return ret;
+}
+
+static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
+{
+	struct amd_cpudata *cpudata = policy->driver_data;
+	u8 floor_perf;
+	u64 value;
+	int ret;
+
+	if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
+		return 0;
+
+	ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, &value);
+	if (ret) {
+		pr_err("failed to read CPPC REQ2 value. Error (%d)\n", ret);
+		return ret;
+	}
+
+	WRITE_ONCE(cpudata->cppc_req2_cached, value);
+	floor_perf = FIELD_GET(AMD_CPPC_FLOOR_PERF_MASK,
+			       cpudata->cppc_req2_cached);
+
+	/* Set a sane value for floor_perf if the default value is invalid */
+	if (floor_perf < cpudata->perf.lowest_perf) {
+		floor_perf = cpudata->perf.nominal_perf;
+		ret = amd_pstate_set_floor_perf(policy, floor_perf);
+		if (ret)
+			return ret;
+	}
+
+	cpudata->bios_floor_perf = floor_perf;
+
+	return 0;
+}
+
 static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp)
 {
 	struct amd_cpudata *cpudata = policy->driver_data;
@@ -426,6 +485,7 @@ static int msr_init_perf(struct amd_cpudata *cpudata)
 	perf.lowest_perf = FIELD_GET(AMD_CPPC_LOWEST_PERF_MASK, cap1);
 	WRITE_ONCE(cpudata->perf, perf);
 	WRITE_ONCE(cpudata->prefcore_ranking, FIELD_GET(AMD_CPPC_HIGHEST_PERF_MASK, cap1));
+	WRITE_ONCE(cpudata->floor_perf_cnt, FIELD_GET(AMD_CPPC_FLOOR_PERF_CNT_MASK, cap1));
 
 	return 0;
 }
@@ -1024,6 +1084,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 							      cpudata->nominal_freq,
 							      perf.highest_perf);
 
+	policy->driver_data = cpudata;
 	ret = amd_pstate_cppc_enable(policy);
 	if (ret)
 		goto free_cpudata1;
@@ -1036,6 +1097,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 	if (cpu_feature_enabled(X86_FEATURE_CPPC))
 		policy->fast_switch_possible = true;
 
+	ret = amd_pstate_init_floor_perf(policy);
+	if (ret) {
+		dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
+		goto free_cpudata1;
+	}
+
 	ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
 				   FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
 	if (ret < 0) {
@@ -1050,7 +1117,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 		goto free_cpudata2;
 	}
 
-	policy->driver_data = cpudata;
 
 	if (!current_pstate_driver->adjust_perf)
 		current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
@@ -1062,6 +1128,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 free_cpudata1:
 	pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
 	kfree(cpudata);
+	policy->driver_data = NULL;
 	return ret;
 }
 
@@ -1072,6 +1139,7 @@ static void amd_pstate_cpu_exit(struct cpufreq_policy *policy)
 
 	/* Reset CPPC_REQ MSR to the BIOS value */
 	amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
+	amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
 
 	freq_qos_remove_request(&cpudata->req[1]);
 	freq_qos_remove_request(&cpudata->req[0]);
@@ -1598,6 +1666,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
 	if (ret)
 		goto free_cpudata1;
 
+	ret = amd_pstate_init_floor_perf(policy);
+	if (ret) {
+		dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
+		goto free_cpudata1;
+	}
+
 	current_pstate_driver->adjust_perf = NULL;
 
 	return 0;
@@ -1605,6 +1679,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
 free_cpudata1:
 	pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
 	kfree(cpudata);
+	policy->driver_data = NULL;
 	return ret;
 }
 
@@ -1617,6 +1692,7 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
 
 		/* Reset CPPC_REQ MSR to the BIOS value */
 		amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
+		amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
 
 		kfree(cpudata);
 		policy->driver_data = NULL;
diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
index cb45fdca27a6..f04561da4518 100644
--- a/drivers/cpufreq/amd-pstate.h
+++ b/drivers/cpufreq/amd-pstate.h
@@ -62,9 +62,12 @@ struct amd_aperf_mperf {
  * @cpu: CPU number
  * @req: constraint request to apply
  * @cppc_req_cached: cached performance request hints
+ * @cppc_req2_cached: cached value of MSR_AMD_CPPC_REQ2
  * @perf: cached performance-related data
  * @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
  * 		  priority.
+ * @floor_perf_cnt: Cached value of the number of distinct floor
+ *                  performance levels supported
  * @min_limit_freq: Cached value of policy->min (in khz)
  * @max_limit_freq: Cached value of policy->max (in khz)
  * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
@@ -87,10 +90,13 @@ struct amd_cpudata {
 
 	struct	freq_qos_request req[2];
 	u64	cppc_req_cached;
+	u64	cppc_req2_cached;
 
 	union perf_cached perf;
 
 	u8	prefcore_ranking;
+	u8	floor_perf_cnt;
+	u8	bios_floor_perf;
 	u32	min_limit_freq;
 	u32	max_limit_freq;
 	u32	nominal_freq;
-- 
2.34.1
Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
Posted by Mario Limonciello 1 week, 3 days ago

On 3/20/26 09:43, Gautham R. Shenoy wrote:
> Some future AMD processors have feature named "CPPC Performance
> Priority" which lets userspace specify different floor performance
> levels for different CPUs. The platform firmware takes these different
> floor performance levels into consideration while throttling the CPUs
> under power/thermal constraints. The presence of this feature is
> indicated by bit 16 of the EDX register for CPUID leaf
> 0x80000007. More details can be found in AMD Publication titled "AMD64
> Collaborative Processor Performance Control (CPPC) Performance
> Priority" Revision 1.10.
> 
> The number of distinct floor performance levels supported on the
> platform will be advertised through the bits 32:39 of the
> MSR_AMD_CPPC_CAP1. Bits 0:7 of a new MSR MSR_AMD_CPPC_REQ2
> (0xc00102b5) will be used to specify the desired floor performance
> level for that CPU.
> 
> Add support for the aforementioned MSR_AMD_CPPC_REQ2, and macros for
> parsing and updating the relevant bits from MSR_AMD_CPPC_CAP1 and
> MSR_AMD_CPPC_REQ2.
> 
> On boot if the default value of the MSR_AMD_CPPC_REQ2[7:0] (Floor
> Perf) is lower than CPPC.lowest_perf, and thus invalid, initialize it
> to MSR_AMD_CPPC_CAP1.nominal_perf which is a sane default value.
> 
> Save the boot-time floor_perf during amd_pstate_init_floor_perf(). In
> a subsequent patch it will be restored in the suspend, offline, and
> exit paths, mirroring how bios_min_perf is handled for
> MSR_AMD_CPPC_REQ.
> 
> Link: https://docs.amd.com/v/u/en-US/69206_1.10_AMD64_CPPC_PUB
> Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
> ---
>   arch/x86/include/asm/msr-index.h |  5 ++
>   drivers/cpufreq/amd-pstate.c     | 78 +++++++++++++++++++++++++++++++-
>   drivers/cpufreq/amd-pstate.h     |  6 +++
>   3 files changed, 88 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 6673601246b3..e126c7fb69cf 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -765,12 +765,14 @@
>   #define MSR_AMD_CPPC_CAP2		0xc00102b2
>   #define MSR_AMD_CPPC_REQ		0xc00102b3
>   #define MSR_AMD_CPPC_STATUS		0xc00102b4
> +#define MSR_AMD_CPPC_REQ2		0xc00102b5
>   
>   /* Masks for use with MSR_AMD_CPPC_CAP1 */
>   #define AMD_CPPC_LOWEST_PERF_MASK	GENMASK(7, 0)
>   #define AMD_CPPC_LOWNONLIN_PERF_MASK	GENMASK(15, 8)
>   #define AMD_CPPC_NOMINAL_PERF_MASK	GENMASK(23, 16)
>   #define AMD_CPPC_HIGHEST_PERF_MASK	GENMASK(31, 24)
> +#define AMD_CPPC_FLOOR_PERF_CNT_MASK	GENMASK_ULL(39, 32)
>   
>   /* Masks for use with MSR_AMD_CPPC_REQ */
>   #define AMD_CPPC_MAX_PERF_MASK		GENMASK(7, 0)
> @@ -778,6 +780,9 @@
>   #define AMD_CPPC_DES_PERF_MASK		GENMASK(23, 16)
>   #define AMD_CPPC_EPP_PERF_MASK		GENMASK(31, 24)
>   
> +/* Masks for use with MSR_AMD_CPPC_REQ2 */
> +#define AMD_CPPC_FLOOR_PERF_MASK	GENMASK(7, 0)
> +
>   /* AMD Performance Counter Global Status and Control MSRs */
>   #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS	0xc0000300
>   #define MSR_AMD64_PERF_CNTR_GLOBAL_CTL		0xc0000301
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 4de2037a414c..53b8173ff183 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -329,6 +329,65 @@ static inline int amd_pstate_set_epp(struct cpufreq_policy *policy, u8 epp)
>   	return static_call(amd_pstate_set_epp)(policy, epp);
>   }
>   
> +static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf)
> +{
> +	struct amd_cpudata *cpudata = policy->driver_data;
> +	u64 value, prev;
> +	int ret;
> +
> +	if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
> +		return 0;
> +
> +	value = prev = READ_ONCE(cpudata->cppc_req2_cached);
> +	FIELD_MODIFY(AMD_CPPC_FLOOR_PERF_MASK, &value, perf);
> +
> +	if (value == prev)
> +		return 0;
> +
> +	ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, value);
> +	if (ret) {
> +		pr_err("failed to set CPPC REQ2 value. Error (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	WRITE_ONCE(cpudata->cppc_req2_cached, value);
> +
> +	return ret;
> +}
> +
> +static int amd_pstate_init_floor_perf(struct cpufreq_policy *policy)
> +{
> +	struct amd_cpudata *cpudata = policy->driver_data;
> +	u8 floor_perf;
> +	u64 value;
> +	int ret;
> +
> +	if (!cpu_feature_enabled(X86_FEATURE_CPPC_PERF_PRIO))
> +		return 0;
> +
> +	ret = rdmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ2, &value);
> +	if (ret) {
> +		pr_err("failed to read CPPC REQ2 value. Error (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	WRITE_ONCE(cpudata->cppc_req2_cached, value);
> +	floor_perf = FIELD_GET(AMD_CPPC_FLOOR_PERF_MASK,
> +			       cpudata->cppc_req2_cached);
> +
> +	/* Set a sane value for floor_perf if the default value is invalid */
> +	if (floor_perf < cpudata->perf.lowest_perf) {
> +		floor_perf = cpudata->perf.nominal_perf;
> +		ret = amd_pstate_set_floor_perf(policy, floor_perf);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	cpudata->bios_floor_perf = floor_perf;
> +
> +	return 0;
> +}
> +
>   static int shmem_set_epp(struct cpufreq_policy *policy, u8 epp)
>   {
>   	struct amd_cpudata *cpudata = policy->driver_data;
> @@ -426,6 +485,7 @@ static int msr_init_perf(struct amd_cpudata *cpudata)
>   	perf.lowest_perf = FIELD_GET(AMD_CPPC_LOWEST_PERF_MASK, cap1);
>   	WRITE_ONCE(cpudata->perf, perf);
>   	WRITE_ONCE(cpudata->prefcore_ranking, FIELD_GET(AMD_CPPC_HIGHEST_PERF_MASK, cap1));
> +	WRITE_ONCE(cpudata->floor_perf_cnt, FIELD_GET(AMD_CPPC_FLOOR_PERF_CNT_MASK, cap1));
>   
>   	return 0;
>   }
> @@ -1024,6 +1084,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
>   							      cpudata->nominal_freq,
>   							      perf.highest_perf);
>   
> +	policy->driver_data = cpudata;
>   	ret = amd_pstate_cppc_enable(policy);
>   	if (ret)
>   		goto free_cpudata1;
> @@ -1036,6 +1097,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
>   	if (cpu_feature_enabled(X86_FEATURE_CPPC))
>   		policy->fast_switch_possible = true;
>   
> +	ret = amd_pstate_init_floor_perf(policy);
> +	if (ret) {
> +		dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
> +		goto free_cpudata1;
> +	}
> +
>   	ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
>   				   FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
>   	if (ret < 0) {
> @@ -1050,7 +1117,6 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
>   		goto free_cpudata2;
>   	}
>   
> -	policy->driver_data = cpudata;
>   
>   	if (!current_pstate_driver->adjust_perf)
>   		current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
> @@ -1062,6 +1128,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
>   free_cpudata1:
>   	pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
>   	kfree(cpudata);
> +	policy->driver_data = NULL;
>   	return ret;
>   }
>   
> @@ -1072,6 +1139,7 @@ static void amd_pstate_cpu_exit(struct cpufreq_policy *policy)
>   
>   	/* Reset CPPC_REQ MSR to the BIOS value */
>   	amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
> +	amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
>   
>   	freq_qos_remove_request(&cpudata->req[1]);
>   	freq_qos_remove_request(&cpudata->req[0]);
> @@ -1598,6 +1666,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
>   	if (ret)
>   		goto free_cpudata1;
>   
> +	ret = amd_pstate_init_floor_perf(policy);
> +	if (ret) {
> +		dev_err(dev, "Failed to initialize Floor Perf (%d)\n", ret);
> +		goto free_cpudata1;
> +	}
> +
>   	current_pstate_driver->adjust_perf = NULL;
>   
>   	return 0;
> @@ -1605,6 +1679,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
>   free_cpudata1:
>   	pr_warn("Failed to initialize CPU %d: %d\n", policy->cpu, ret);
>   	kfree(cpudata);
> +	policy->driver_data = NULL;
>   	return ret;
>   }
>   
> @@ -1617,6 +1692,7 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
>   
>   		/* Reset CPPC_REQ MSR to the BIOS value */
>   		amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false);
> +		amd_pstate_set_floor_perf(policy, cpudata->bios_floor_perf);
>   
>   		kfree(cpudata);
>   		policy->driver_data = NULL;
> diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
> index cb45fdca27a6..f04561da4518 100644
> --- a/drivers/cpufreq/amd-pstate.h
> +++ b/drivers/cpufreq/amd-pstate.h
> @@ -62,9 +62,12 @@ struct amd_aperf_mperf {
>    * @cpu: CPU number
>    * @req: constraint request to apply
>    * @cppc_req_cached: cached performance request hints
> + * @cppc_req2_cached: cached value of MSR_AMD_CPPC_REQ2
>    * @perf: cached performance-related data
>    * @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
>    * 		  priority.
> + * @floor_perf_cnt: Cached value of the number of distinct floor
> + *                  performance levels supported
>    * @min_limit_freq: Cached value of policy->min (in khz)
>    * @max_limit_freq: Cached value of policy->max (in khz)
>    * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
> @@ -87,10 +90,13 @@ struct amd_cpudata {
>   
>   	struct	freq_qos_request req[2];
>   	u64	cppc_req_cached;
> +	u64	cppc_req2_cached;
>   
>   	union perf_cached perf;
>   
>   	u8	prefcore_ranking;
> +	u8	floor_perf_cnt;
> +	u8	bios_floor_perf;

It looks like you forgot to update doc for bios_floor_perf

>   	u32	min_limit_freq;
>   	u32	max_limit_freq;
>   	u32	nominal_freq;
Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
Posted by Gautham R. Shenoy 1 week, 1 day ago
Hello Mario,

On Tue, Mar 24, 2026 at 04:38:07PM -0500, Mario Limonciello wrote:
> 
> 

[..snip..]

> > index cb45fdca27a6..f04561da4518 100644
> > --- a/drivers/cpufreq/amd-pstate.h
> > +++ b/drivers/cpufreq/amd-pstate.h
> > @@ -62,9 +62,12 @@ struct amd_aperf_mperf {
> >    * @cpu: CPU number
> >    * @req: constraint request to apply
> >    * @cppc_req_cached: cached performance request hints
> > + * @cppc_req2_cached: cached value of MSR_AMD_CPPC_REQ2
> >    * @perf: cached performance-related data
> >    * @prefcore_ranking: the preferred core ranking, the higher value indicates a higher
> >    * 		  priority.
> > + * @floor_perf_cnt: Cached value of the number of distinct floor
> > + *                  performance levels supported
> >    * @min_limit_freq: Cached value of policy->min (in khz)
> >    * @max_limit_freq: Cached value of policy->max (in khz)
> >    * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
> > @@ -87,10 +90,13 @@ struct amd_cpudata {
> >   	struct	freq_qos_request req[2];
> >   	u64	cppc_req_cached;
> > +	u64	cppc_req2_cached;
> >   	union perf_cached perf;
> >   	u8	prefcore_ranking;
> > +	u8	floor_perf_cnt;
> > +	u8	bios_floor_perf;
> 
> It looks like you forgot to update doc for bios_floor_perf

Thanks for catching this. I will add the doc for bios_floor_perf in v4.


-- 
Thanks and Regards
gautham.
Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
Posted by K Prateek Nayak 1 week, 3 days ago
Hello Mario,

On 3/25/2026 3:08 AM, Mario Limonciello wrote:
>>    * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
>> @@ -87,10 +90,13 @@ struct amd_cpudata {
>>         struct    freq_qos_request req[2];
>>       u64    cppc_req_cached;
>> +    u64    cppc_req2_cached;
>>         union perf_cached perf;
>>         u8    prefcore_ranking;
>> +    u8    floor_perf_cnt;
>> +    u8    bios_floor_perf;
> 
> It looks like you forgot to update doc for bios_floor_perf

"bios_floor_perf" is an internal detail that caches the initial state of
"FloorPerf" from CPPC_REQ2 when the driver is loaded.

It is only used to restore the FloorPerf to the original when the CPU is
offlined, the driver unloaded, or when the CPU is suspended. This
essentially resets the state of the CPU to what it was at the boot so a
kexec, driver switch can start off afresh from the BIOS defaults.

User can read amd_pstate_floor_freq just after the boot to know what the
default is. Do we really need to expose this?

> 
>>       u32    min_limit_freq;
>>       u32    max_limit_freq;
>>       u32    nominal_freq;
> 

-- 
Thanks and Regards,
Prateek

Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
Posted by K Prateek Nayak 1 week, 3 days ago
On 3/25/2026 9:39 AM, K Prateek Nayak wrote:
> Hello Mario,
> 
> On 3/25/2026 3:08 AM, Mario Limonciello wrote:
>>>    * @nominal_freq: the frequency (in khz) that mapped to nominal_perf
>>> @@ -87,10 +90,13 @@ struct amd_cpudata {
>>>         struct    freq_qos_request req[2];
>>>       u64    cppc_req_cached;
>>> +    u64    cppc_req2_cached;
>>>         union perf_cached perf;
>>>         u8    prefcore_ranking;
>>> +    u8    floor_perf_cnt;
>>> +    u8    bios_floor_perf;
>>
>> It looks like you forgot to update doc for bios_floor_perf

Me realizes you meant the comment above the stuct! Sorry for the noise.

_Me goes and grabs a coffee to wake myself up_

> 
> "bios_floor_perf" is an internal detail that caches the initial state of
> "FloorPerf" from CPPC_REQ2 when the driver is loaded.
> 
> It is only used to restore the FloorPerf to the original when the CPU is
> offlined, the driver unloaded, or when the CPU is suspended. This
> essentially resets the state of the CPU to what it was at the boot so a
> kexec, driver switch can start off afresh from the BIOS defaults.
> 
> User can read amd_pstate_floor_freq just after the boot to know what the
> default is. Do we really need to expose this?
> 
>>
>>>       u32    min_limit_freq;
>>>       u32    max_limit_freq;
>>>       u32    nominal_freq;
>>
> 

-- 
Thanks and Regards,
Prateek