From: Mario Limonciello <mario.limonciello@amd.com>
To: "Gautham R. Shenoy" <gautham.shenoy@amd.com>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Viresh Kumar <viresh.kumar@linaro.org>,
K Prateek Nayak <kprateek.nayak@amd.com>
Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org
Subject: Re: [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF
Date: Tue, 24 Mar 2026 16:38:07 -0500 [thread overview]
Message-ID: <48262f07-a852-44e0-92a0-1215bc48e9cf@amd.com> (raw)
In-Reply-To: <20260320144321.18543-6-gautham.shenoy@amd.com>
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;
next prev parent reply other threads:[~2026-03-24 21:38 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-20 14:43 [PATCH v3 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 01/12] amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init() Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 02/12] amd-pstate: Update cppc_req_cached in fast_switch case Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 03/12] amd-pstate: Make certain freq_attrs conditionally visible Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 04/12] x86/cpufeatures: Add AMD CPPC Performance Priority feature Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF Gautham R. Shenoy
2026-03-24 21:38 ` Mario Limonciello [this message]
2026-03-25 4:09 ` K Prateek Nayak
2026-03-25 4:18 ` K Prateek Nayak
2026-03-26 11:30 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count Gautham R. Shenoy
2026-03-24 21:39 ` Mario Limonciello
2026-03-20 14:43 ` [PATCH v3 07/12] amd-pstate: Introduce a tracepoint trace_amd_pstate_cppc_req2() Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 08/12] amd-pstate-ut: Add ability to run a single testcase Gautham R. Shenoy
2026-03-23 20:21 ` Mario Limonciello (AMD) (kernel.org)
2026-03-24 4:29 ` Gautham R. Shenoy
2026-03-24 4:34 ` Mario Limonciello
2026-03-25 4:28 ` K Prateek Nayak
2026-03-25 13:45 ` Mario Limonciello
2026-03-26 11:29 ` Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 09/12] amd-pstate-ut: Add a testcase to validate the visibility of driver attributes Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 10/12] Documentation/amd-pstate: List amd_pstate_hw_prefcore sysfs file Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 11/12] Documentation/amd-pstate: List amd_pstate_prefcore_ranking " Gautham R. Shenoy
2026-03-20 14:43 ` [PATCH v3 12/12] Documentation/amd-pstate: Add documentation for amd_pstate_floor_{freq,count} Gautham R. Shenoy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48262f07-a852-44e0-92a0-1215bc48e9cf@amd.com \
--to=mario.limonciello@amd.com \
--cc=gautham.shenoy@amd.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®