* [PATCH 0/2] ACPI: CPPC: Add CPPC v4 support (ACPI 6.6)
@ 2026-04-27 5:18 Sumit Gupta
2026-04-27 5:18 ` [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4 Sumit Gupta
2026-04-27 5:18 ` [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support Sumit Gupta
0 siblings, 2 replies; 10+ messages in thread
From: Sumit Gupta @ 2026-04-27 5:18 UTC (permalink / raw)
To: rafael, viresh.kumar, lenb, pierre.gondois, zhenglifeng1,
zhanjie9, mario.limonciello, saket.dumbre, linux-acpi,
linux-kernel, linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu, sumitg
Add initial kernel support for CPPC v4 (ACPI 6.6, Section 8.4.6),
which extends the _CPC package from 23 to 25 entries with two
optional fields:
- OSPM Nominal Performance (8.4.6.1.2.6): write-only register
used by OSPM to tell the platform what it considers nominal.
The platform classifies performance above this as boost and
below as throttle for power/thermal decisions.
- Resource Priority (8.4.6.1.2.7): Package of Resource Priority
Register Descriptor sub-packages. Full parsing is not yet
implemented; such entries are marked as unsupported.
Patch 1: Add v4 _CPC parsing - validate the 25-entry layout,
handle the Resource Priority package, and mark the two new
registers optional.
Patch 2: cppc_set_ospm_nominal_perf() API, write-only
acpi_cppc/ospm_nominal_perf sysfs attribute, and init to platform
nominal during cppc_cpufreq policy init.
Sumit Gupta (2):
ACPI: CPPC: Add support for CPPC v4
ACPI: CPPC: Add ospm_nominal_perf support
drivers/acpi/cppc_acpi.c | 66 ++++++++++++++++++++++++++++++----
drivers/cpufreq/cppc_cpufreq.c | 10 ++++++
include/acpi/cppc_acpi.h | 13 +++++--
3 files changed, 81 insertions(+), 8 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
2026-04-27 5:18 [PATCH 0/2] ACPI: CPPC: Add CPPC v4 support (ACPI 6.6) Sumit Gupta
@ 2026-04-27 5:18 ` Sumit Gupta
2026-04-27 7:06 ` zhenglifeng (A)
2026-04-27 15:37 ` Mario Limonciello
2026-04-27 5:18 ` [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support Sumit Gupta
1 sibling, 2 replies; 10+ messages in thread
From: Sumit Gupta @ 2026-04-27 5:18 UTC (permalink / raw)
To: rafael, viresh.kumar, lenb, pierre.gondois, zhenglifeng1,
zhanjie9, mario.limonciello, saket.dumbre, linux-acpi,
linux-kernel, linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu, sumitg
CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
_CPC package:
1. OSPM Nominal Performance (8.4.6.1.2.6): A write-only register that
lets OSPM inform the platform what it considers nominal performance.
The platform classifies performance above this level as boost and
below as throttle for its power/thermal decisions.
2. Resource Priority (8.4.6.1.2.7): A Package of Resource Priority
Register Descriptor sub-packages that allow OSPM to set relative
priority among processors for shared resources (boost, throttle,
L2/L3 cache, memory bandwidth). Parsing the full structure is not
yet supported; such entries are marked as unsupported.
Add v4 _CPC table parsing (25 entries) and update REG_OPTIONAL to
mark the two new registers as optional.
Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
---
drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------
include/acpi/cppc_acpi.h | 8 ++++++--
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 2e91c5a97761..a1c91ce20cc8 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -134,7 +134,7 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
* cpc_regs[] with the corresponding index. 0 means mandatory and 1
* means optional.
*/
-#define REG_OPTIONAL (0x1FC7D0)
+#define REG_OPTIONAL (0x7FC7D0)
/*
* Use the index of the register in per-cpu cpc_regs[] to check if
@@ -751,18 +751,19 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
/*
* Disregard _CPC if the number of entries in the return package is not
* as expected, but support future revisions being proper supersets of
- * the v3 and only causing more entries to be returned by _CPC.
+ * the v4 and only causing more entries to be returned by _CPC.
*/
if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) ||
(cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) ||
- (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) {
+ (cpc_rev == CPPC_V4_REV && num_ent != CPPC_V4_NUM_ENT) ||
+ (cpc_rev > CPPC_V4_REV && num_ent <= CPPC_V4_NUM_ENT)) {
pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n",
num_ent, pr->id);
goto out_free;
}
- if (cpc_rev > CPPC_V3_REV) {
- num_ent = CPPC_V3_NUM_ENT;
- cpc_rev = CPPC_V3_REV;
+ if (cpc_rev > CPPC_V4_REV) {
+ num_ent = CPPC_V4_NUM_ENT;
+ cpc_rev = CPPC_V4_REV;
}
cpc_ptr->num_entries = num_ent;
@@ -845,6 +846,17 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
+ } else if (cpc_obj->type == ACPI_TYPE_PACKAGE) {
+ /*
+ * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority
+ * as a Package of Resource Priority Register Descriptor
+ * sub-packages. Parsing the full structure is not yet
+ * supported; mark the register as unsupported for now.
+ */
+ pr_debug("CPU:%d entry %d: package type not supported\n",
+ pr->id, i);
+ cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
+ cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = 0;
} else {
pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n",
i, pr->id);
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index d1f02ceec4f9..8693890a7275 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -17,16 +17,18 @@
#include <acpi/pcc.h>
#include <acpi/processor.h>
-/* CPPCv2 and CPPCv3 support */
+/* CPPCv2, CPPCv3 and CPPCv4 support */
#define CPPC_V2_REV 2
#define CPPC_V3_REV 3
+#define CPPC_V4_REV 4
#define CPPC_V2_NUM_ENT 21
#define CPPC_V3_NUM_ENT 23
+#define CPPC_V4_NUM_ENT 25
#define PCC_CMD_COMPLETE_MASK (1 << 0)
#define PCC_ERROR_MASK (1 << 2)
-#define MAX_CPC_REG_ENT 21
+#define MAX_CPC_REG_ENT 23
/* CPPC specific PCC commands. */
#define CMD_READ 0
@@ -109,6 +111,8 @@ enum cppc_regs {
REFERENCE_PERF,
LOWEST_FREQ,
NOMINAL_FREQ,
+ OSPM_NOMINAL_PERF,
+ RESOURCE_PRIORITY,
};
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support
2026-04-27 5:18 [PATCH 0/2] ACPI: CPPC: Add CPPC v4 support (ACPI 6.6) Sumit Gupta
2026-04-27 5:18 ` [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4 Sumit Gupta
@ 2026-04-27 5:18 ` Sumit Gupta
2026-04-27 15:36 ` Mario Limonciello
1 sibling, 1 reply; 10+ messages in thread
From: Sumit Gupta @ 2026-04-27 5:18 UTC (permalink / raw)
To: rafael, viresh.kumar, lenb, pierre.gondois, zhenglifeng1,
zhanjie9, mario.limonciello, saket.dumbre, linux-acpi,
linux-kernel, linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu, sumitg
Add acpi_cppc/ospm_nominal_perf sysfs attribute (write-only) and
cppc_set_ospm_nominal_perf() API for the OSPM Nominal Performance
register (ACPI 6.6, Section 8.4.6.1.2.6).
The register conveys the desired nominal performance level at which
the platform may run. OSPM can request a lower level than platform
nominal. Valid range is [Lowest Performance, Nominal Performance].
The value tells the platform what OSPM considers nominal. The
platform classifies performance above this as boosted and below as
throttled. It uses that for its power/thermal decisions.
Initialize to platform nominal at policy init. Override via sysfs
if needed.
Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
---
drivers/acpi/cppc_acpi.c | 42 ++++++++++++++++++++++++++++++++++
drivers/cpufreq/cppc_cpufreq.c | 10 ++++++++
include/acpi/cppc_acpi.h | 5 ++++
3 files changed, 57 insertions(+)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index a1c91ce20cc8..83b4b14652fb 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -155,6 +155,10 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
static struct kobj_attribute _name = \
__ATTR(_name, 0444, show_##_name, NULL)
+#define define_one_cppc_wo(_name) \
+static struct kobj_attribute _name = \
+__ATTR(_name, 0200, NULL, store_##_name)
+
#define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj)
#define show_cppc_data(access_fn, struct_name, member_name) \
@@ -211,6 +215,26 @@ static ssize_t show_feedback_ctrs(struct kobject *kobj,
}
define_one_cppc_ro(feedback_ctrs);
+static ssize_t store_ospm_nominal_perf(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
+ u64 val;
+ int ret;
+
+ ret = kstrtou64(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ ret = cppc_set_ospm_nominal_perf(cpc_ptr->cpu_id, val);
+ if (ret)
+ return ret;
+
+ return count;
+}
+define_one_cppc_wo(ospm_nominal_perf);
+
static struct attribute *cppc_attrs[] = {
&feedback_ctrs.attr,
&reference_perf.attr,
@@ -222,6 +246,7 @@ static struct attribute *cppc_attrs[] = {
&nominal_perf.attr,
&nominal_freq.attr,
&lowest_freq.attr,
+ &ospm_nominal_perf.attr,
NULL
};
ATTRIBUTE_GROUPS(cppc);
@@ -1683,6 +1708,23 @@ int cppc_set_epp(int cpu, u64 epp_val)
}
EXPORT_SYMBOL_GPL(cppc_set_epp);
+/**
+ * cppc_set_ospm_nominal_perf() - Write OSPM Nominal Performance register.
+ * @cpu: CPU on which to write register.
+ * @ospm_nominal_perf: Value to write to the OSPM Nominal Performance register.
+ *
+ * OSPM Nominal Performance allows OSPM to inform the platform of the nominal
+ * performance level it intends to maintain. This is a write-only register per
+ * ACPI specification.
+ *
+ * Return: 0 for success, -EOPNOTSUPP if not supported, -EIO otherwise.
+ */
+int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf)
+{
+ return cppc_set_reg_val(cpu, OSPM_NOMINAL_PERF, ospm_nominal_perf);
+}
+EXPORT_SYMBOL_GPL(cppc_set_ospm_nominal_perf);
+
/**
* cppc_get_auto_act_window() - Read autonomous activity window register.
* @cpu: CPU from which to read register.
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 7e7f9dfb7a24..d06cba963550 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -715,6 +715,16 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto out;
}
+ /*
+ * Initialize OSPM Nominal Performance to inform firmware of
+ * OSPM's nominal level. Performance above this value = boost;
+ * below = throttle. Uses platform nominal by default.
+ */
+ ret = cppc_set_ospm_nominal_perf(cpu, caps->nominal_perf);
+ if (ret && ret != -EOPNOTSUPP)
+ pr_debug("Failed to set ospm_nominal_perf for CPU%d: %d\n",
+ cpu, ret);
+
cppc_cpufreq_cpu_fie_init(policy);
return 0;
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index 8693890a7275..ad1035b0e1de 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -180,6 +180,7 @@ extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf);
extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable);
extern int cppc_set_epp(int cpu, u64 epp_val);
+extern int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf);
extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window);
extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window);
extern int cppc_get_auto_sel(int cpu, bool *enable);
@@ -266,6 +267,10 @@ static inline int cppc_set_epp(int cpu, u64 epp_val)
{
return -EOPNOTSUPP;
}
+static inline int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf)
+{
+ return -EOPNOTSUPP;
+}
static inline int cppc_get_auto_act_window(int cpu, u64 *auto_act_window)
{
return -EOPNOTSUPP;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
2026-04-27 5:18 ` [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4 Sumit Gupta
@ 2026-04-27 7:06 ` zhenglifeng (A)
2026-04-27 8:04 ` Sumit Gupta
2026-04-27 15:37 ` Mario Limonciello
1 sibling, 1 reply; 10+ messages in thread
From: zhenglifeng (A) @ 2026-04-27 7:06 UTC (permalink / raw)
To: Sumit Gupta, rafael, viresh.kumar, lenb, pierre.gondois, zhanjie9,
mario.limonciello, saket.dumbre, linux-acpi, linux-kernel,
linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu
It seems that mario has sent a similar patch:
https://lore.kernel.org/all/20260427035520.1427080-3-superm1@kernel.org/
On 4/27/2026 1:18 PM, Sumit Gupta wrote:
> CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
> _CPC package:
>
> 1. OSPM Nominal Performance (8.4.6.1.2.6): A write-only register that
> lets OSPM inform the platform what it considers nominal performance.
> The platform classifies performance above this level as boost and
> below as throttle for its power/thermal decisions.
>
> 2. Resource Priority (8.4.6.1.2.7): A Package of Resource Priority
> Register Descriptor sub-packages that allow OSPM to set relative
> priority among processors for shared resources (boost, throttle,
> L2/L3 cache, memory bandwidth). Parsing the full structure is not
> yet supported; such entries are marked as unsupported.
>
> Add v4 _CPC table parsing (25 entries) and update REG_OPTIONAL to
> mark the two new registers as optional.
>
> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
> ---
> drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------
> include/acpi/cppc_acpi.h | 8 ++++++--
> 2 files changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
> index 2e91c5a97761..a1c91ce20cc8 100644
> --- a/drivers/acpi/cppc_acpi.c
> +++ b/drivers/acpi/cppc_acpi.c
> @@ -134,7 +134,7 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
> * cpc_regs[] with the corresponding index. 0 means mandatory and 1
> * means optional.
> */
> -#define REG_OPTIONAL (0x1FC7D0)
> +#define REG_OPTIONAL (0x7FC7D0)
>
> /*
> * Use the index of the register in per-cpu cpc_regs[] to check if
> @@ -751,18 +751,19 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
> /*
> * Disregard _CPC if the number of entries in the return package is not
> * as expected, but support future revisions being proper supersets of
> - * the v3 and only causing more entries to be returned by _CPC.
> + * the v4 and only causing more entries to be returned by _CPC.
> */
> if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) ||
> (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) ||
> - (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) {
> + (cpc_rev == CPPC_V4_REV && num_ent != CPPC_V4_NUM_ENT) ||
> + (cpc_rev > CPPC_V4_REV && num_ent <= CPPC_V4_NUM_ENT)) {
> pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n",
> num_ent, pr->id);
> goto out_free;
> }
> - if (cpc_rev > CPPC_V3_REV) {
> - num_ent = CPPC_V3_NUM_ENT;
> - cpc_rev = CPPC_V3_REV;
> + if (cpc_rev > CPPC_V4_REV) {
> + num_ent = CPPC_V4_NUM_ENT;
> + cpc_rev = CPPC_V4_REV;
> }
>
> cpc_ptr->num_entries = num_ent;
> @@ -845,6 +846,17 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
>
> cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
> memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
> + } else if (cpc_obj->type == ACPI_TYPE_PACKAGE) {
> + /*
> + * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority
> + * as a Package of Resource Priority Register Descriptor
> + * sub-packages. Parsing the full structure is not yet
> + * supported; mark the register as unsupported for now.
> + */
> + pr_debug("CPU:%d entry %d: package type not supported\n",
> + pr->id, i);
> + cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
> + cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = 0;
> } else {
> pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n",
> i, pr->id);
> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
> index d1f02ceec4f9..8693890a7275 100644
> --- a/include/acpi/cppc_acpi.h
> +++ b/include/acpi/cppc_acpi.h
> @@ -17,16 +17,18 @@
> #include <acpi/pcc.h>
> #include <acpi/processor.h>
>
> -/* CPPCv2 and CPPCv3 support */
> +/* CPPCv2, CPPCv3 and CPPCv4 support */
> #define CPPC_V2_REV 2
> #define CPPC_V3_REV 3
> +#define CPPC_V4_REV 4
> #define CPPC_V2_NUM_ENT 21
> #define CPPC_V3_NUM_ENT 23
> +#define CPPC_V4_NUM_ENT 25
>
> #define PCC_CMD_COMPLETE_MASK (1 << 0)
> #define PCC_ERROR_MASK (1 << 2)
>
> -#define MAX_CPC_REG_ENT 21
> +#define MAX_CPC_REG_ENT 23
>
> /* CPPC specific PCC commands. */
> #define CMD_READ 0
> @@ -109,6 +111,8 @@ enum cppc_regs {
> REFERENCE_PERF,
> LOWEST_FREQ,
> NOMINAL_FREQ,
> + OSPM_NOMINAL_PERF,
> + RESOURCE_PRIORITY,
> };
>
> /*
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
2026-04-27 7:06 ` zhenglifeng (A)
@ 2026-04-27 8:04 ` Sumit Gupta
2026-04-27 15:33 ` Mario Limonciello
0 siblings, 1 reply; 10+ messages in thread
From: Sumit Gupta @ 2026-04-27 8:04 UTC (permalink / raw)
To: zhenglifeng (A), rafael, viresh.kumar, lenb, pierre.gondois,
zhanjie9, mario.limonciello, saket.dumbre, linux-acpi,
linux-kernel, linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu, sumitg
On 27/04/26 12:36, zhenglifeng (A) wrote:
> External email: Use caution opening links or attachments
>
>
> It seems that mario has sent a similar patch:
>
> https://lore.kernel.org/all/20260427035520.1427080-3-superm1@kernel.org/
Thank you for sharing.
Yes, both look similar with below two change.
1. REG_OPTIONAL needs the 0x1FC7D0 -> 0x7FC7D0 update to mark
the two new registers optional. This is present in my [PATCH 1/2].
2. For Resource Priority, pkg_data added to cpc_entry.
This is present in Mario's [PATCH 2/6].
Hi Mario,
How would you like to proceed? A few options:
(a) Let both CPPCv4 patches from this series go separately.
(b) Fold the REG_OPTIONAL update from my patch 1/2 into your
patch, and pull my patch 2/2 into your series.
(c) Anything else you'd prefer.
Either way works for me.
Thank you,
Sumit Gupta
>
> On 4/27/2026 1:18 PM, Sumit Gupta wrote:
>> CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
>> _CPC package:
>>
>> 1. OSPM Nominal Performance (8.4.6.1.2.6): A write-only register that
>> lets OSPM inform the platform what it considers nominal performance.
>> The platform classifies performance above this level as boost and
>> below as throttle for its power/thermal decisions.
>>
>> 2. Resource Priority (8.4.6.1.2.7): A Package of Resource Priority
>> Register Descriptor sub-packages that allow OSPM to set relative
>> priority among processors for shared resources (boost, throttle,
>> L2/L3 cache, memory bandwidth). Parsing the full structure is not
>> yet supported; such entries are marked as unsupported.
>>
>> Add v4 _CPC table parsing (25 entries) and update REG_OPTIONAL to
>> mark the two new registers as optional.
>>
>> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
>> ---
>> drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------
>> include/acpi/cppc_acpi.h | 8 ++++++--
>> 2 files changed, 24 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
>> index 2e91c5a97761..a1c91ce20cc8 100644
>> --- a/drivers/acpi/cppc_acpi.c
>> +++ b/drivers/acpi/cppc_acpi.c
>> @@ -134,7 +134,7 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
>> * cpc_regs[] with the corresponding index. 0 means mandatory and 1
>> * means optional.
>> */
>> -#define REG_OPTIONAL (0x1FC7D0)
>> +#define REG_OPTIONAL (0x7FC7D0)
>>
>> /*
>> * Use the index of the register in per-cpu cpc_regs[] to check if
>> @@ -751,18 +751,19 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
>> /*
>> * Disregard _CPC if the number of entries in the return package is not
>> * as expected, but support future revisions being proper supersets of
>> - * the v3 and only causing more entries to be returned by _CPC.
>> + * the v4 and only causing more entries to be returned by _CPC.
>> */
>> if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) ||
>> (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) ||
>> - (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) {
>> + (cpc_rev == CPPC_V4_REV && num_ent != CPPC_V4_NUM_ENT) ||
>> + (cpc_rev > CPPC_V4_REV && num_ent <= CPPC_V4_NUM_ENT)) {
>> pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n",
>> num_ent, pr->id);
>> goto out_free;
>> }
>> - if (cpc_rev > CPPC_V3_REV) {
>> - num_ent = CPPC_V3_NUM_ENT;
>> - cpc_rev = CPPC_V3_REV;
>> + if (cpc_rev > CPPC_V4_REV) {
>> + num_ent = CPPC_V4_NUM_ENT;
>> + cpc_rev = CPPC_V4_REV;
>> }
>>
>> cpc_ptr->num_entries = num_ent;
>> @@ -845,6 +846,17 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
>>
>> cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
>> memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
>> + } else if (cpc_obj->type == ACPI_TYPE_PACKAGE) {
>> + /*
>> + * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority
>> + * as a Package of Resource Priority Register Descriptor
>> + * sub-packages. Parsing the full structure is not yet
>> + * supported; mark the register as unsupported for now.
>> + */
>> + pr_debug("CPU:%d entry %d: package type not supported\n",
>> + pr->id, i);
>> + cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
>> + cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = 0;
>> } else {
>> pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n",
>> i, pr->id);
>> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
>> index d1f02ceec4f9..8693890a7275 100644
>> --- a/include/acpi/cppc_acpi.h
>> +++ b/include/acpi/cppc_acpi.h
>> @@ -17,16 +17,18 @@
>> #include <acpi/pcc.h>
>> #include <acpi/processor.h>
>>
>> -/* CPPCv2 and CPPCv3 support */
>> +/* CPPCv2, CPPCv3 and CPPCv4 support */
>> #define CPPC_V2_REV 2
>> #define CPPC_V3_REV 3
>> +#define CPPC_V4_REV 4
>> #define CPPC_V2_NUM_ENT 21
>> #define CPPC_V3_NUM_ENT 23
>> +#define CPPC_V4_NUM_ENT 25
>>
>> #define PCC_CMD_COMPLETE_MASK (1 << 0)
>> #define PCC_ERROR_MASK (1 << 2)
>>
>> -#define MAX_CPC_REG_ENT 21
>> +#define MAX_CPC_REG_ENT 23
>>
>> /* CPPC specific PCC commands. */
>> #define CMD_READ 0
>> @@ -109,6 +111,8 @@ enum cppc_regs {
>> REFERENCE_PERF,
>> LOWEST_FREQ,
>> NOMINAL_FREQ,
>> + OSPM_NOMINAL_PERF,
>> + RESOURCE_PRIORITY,
>> };
>>
>> /*
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
2026-04-27 8:04 ` Sumit Gupta
@ 2026-04-27 15:33 ` Mario Limonciello
2026-04-28 12:53 ` Sumit Gupta
0 siblings, 1 reply; 10+ messages in thread
From: Mario Limonciello @ 2026-04-27 15:33 UTC (permalink / raw)
To: Sumit Gupta, zhenglifeng (A), rafael, viresh.kumar, lenb,
pierre.gondois, zhanjie9, saket.dumbre, linux-acpi, linux-kernel,
linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu
On 4/27/26 03:04, Sumit Gupta wrote:
>
> On 27/04/26 12:36, zhenglifeng (A) wrote:
>> External email: Use caution opening links or attachments
>>
>>
>> It seems that mario has sent a similar patch:
>>
>> https://lore.kernel.org/all/20260427035520.1427080-3-superm1@kernel.org/
>
>
> Thank you for sharing.
> Yes, both look similar with below two change.
> 1. REG_OPTIONAL needs the 0x1FC7D0 -> 0x7FC7D0 update to mark
> the two new registers optional. This is present in my [PATCH 1/2].
> 2. For Resource Priority, pkg_data added to cpc_entry.
> This is present in Mario's [PATCH 2/6].
>
>
> Hi Mario,
> How would you like to proceed? A few options:
> (a) Let both CPPCv4 patches from this series go separately.
> (b) Fold the REG_OPTIONAL update from my patch 1/2 into your
> patch, and pull my patch 2/2 into your series.
> (c) Anything else you'd prefer.
> Either way works for me.
>
> Thank you,
> Sumit Gupta
>
Reviewing yours points out that I totally missed updating REG_OPTIONAL
with the two new ACPI 6.7 fields being optional too.
In my series I only add in CPPv4 so I can build on top of the changes
for CPPCv5.
So - I would say we should let your patches merge for v4 and I'll drop
the relevant ones from my series and rebase mine on top of your work.
>
>>
>> On 4/27/2026 1:18 PM, Sumit Gupta wrote:
>>> CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
>>> _CPC package:
>>>
>>> 1. OSPM Nominal Performance (8.4.6.1.2.6): A write-only register that
>>> lets OSPM inform the platform what it considers nominal performance.
>>> The platform classifies performance above this level as boost and
>>> below as throttle for its power/thermal decisions.
>>>
>>> 2. Resource Priority (8.4.6.1.2.7): A Package of Resource Priority
>>> Register Descriptor sub-packages that allow OSPM to set relative
>>> priority among processors for shared resources (boost, throttle,
>>> L2/L3 cache, memory bandwidth). Parsing the full structure is not
>>> yet supported; such entries are marked as unsupported.
>>>
>>> Add v4 _CPC table parsing (25 entries) and update REG_OPTIONAL to
>>> mark the two new registers as optional.
>>>
>>> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
>>> ---
>>> drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------
>>> include/acpi/cppc_acpi.h | 8 ++++++--
>>> 2 files changed, 24 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
>>> index 2e91c5a97761..a1c91ce20cc8 100644
>>> --- a/drivers/acpi/cppc_acpi.c
>>> +++ b/drivers/acpi/cppc_acpi.c
>>> @@ -134,7 +134,7 @@ static DEFINE_PER_CPU(struct cpc_desc *,
>>> cpc_desc_ptr);
>>> * cpc_regs[] with the corresponding index. 0 means mandatory and 1
>>> * means optional.
>>> */
>>> -#define REG_OPTIONAL (0x1FC7D0)
>>> +#define REG_OPTIONAL (0x7FC7D0)
>>>
>>> /*
>>> * Use the index of the register in per-cpu cpc_regs[] to check if
>>> @@ -751,18 +751,19 @@ int acpi_cppc_processor_probe(struct
>>> acpi_processor *pr)
>>> /*
>>> * Disregard _CPC if the number of entries in the return
>>> package is not
>>> * as expected, but support future revisions being proper
>>> supersets of
>>> - * the v3 and only causing more entries to be returned by _CPC.
>>> + * the v4 and only causing more entries to be returned by _CPC.
>>> */
>>> if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) ||
>>> (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) ||
>>> - (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) {
>>> + (cpc_rev == CPPC_V4_REV && num_ent != CPPC_V4_NUM_ENT) ||
>>> + (cpc_rev > CPPC_V4_REV && num_ent <= CPPC_V4_NUM_ENT)) {
>>> pr_debug("Unexpected number of _CPC return package
>>> entries (%d) for CPU:%d\n",
>>> num_ent, pr->id);
>>> goto out_free;
>>> }
>>> - if (cpc_rev > CPPC_V3_REV) {
>>> - num_ent = CPPC_V3_NUM_ENT;
>>> - cpc_rev = CPPC_V3_REV;
>>> + if (cpc_rev > CPPC_V4_REV) {
>>> + num_ent = CPPC_V4_NUM_ENT;
>>> + cpc_rev = CPPC_V4_REV;
>>> }
>>>
>>> cpc_ptr->num_entries = num_ent;
>>> @@ -845,6 +846,17 @@ int acpi_cppc_processor_probe(struct
>>> acpi_processor *pr)
>>>
>>> cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
>>> memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg,
>>> gas_t, sizeof(*gas_t));
>>> + } else if (cpc_obj->type == ACPI_TYPE_PACKAGE) {
>>> + /*
>>> + * ACPI 6.6, s8.4.6.1.2.7 defines Resource
>>> Priority
>>> + * as a Package of Resource Priority Register
>>> Descriptor
>>> + * sub-packages. Parsing the full structure is
>>> not yet
>>> + * supported; mark the register as unsupported
>>> for now.
>>> + */
>>> + pr_debug("CPU:%d entry %d: package type not
>>> supported\n",
>>> + pr->id, i);
>>> + cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
>>> + cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = 0;
>>> } else {
>>> pr_debug("Invalid entry type (%d) in _CPC for
>>> CPU:%d\n",
>>> i, pr->id);
>>> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
>>> index d1f02ceec4f9..8693890a7275 100644
>>> --- a/include/acpi/cppc_acpi.h
>>> +++ b/include/acpi/cppc_acpi.h
>>> @@ -17,16 +17,18 @@
>>> #include <acpi/pcc.h>
>>> #include <acpi/processor.h>
>>>
>>> -/* CPPCv2 and CPPCv3 support */
>>> +/* CPPCv2, CPPCv3 and CPPCv4 support */
>>> #define CPPC_V2_REV 2
>>> #define CPPC_V3_REV 3
>>> +#define CPPC_V4_REV 4
>>> #define CPPC_V2_NUM_ENT 21
>>> #define CPPC_V3_NUM_ENT 23
>>> +#define CPPC_V4_NUM_ENT 25
>>>
>>> #define PCC_CMD_COMPLETE_MASK (1 << 0)
>>> #define PCC_ERROR_MASK (1 << 2)
>>>
>>> -#define MAX_CPC_REG_ENT 21
>>> +#define MAX_CPC_REG_ENT 23
>>>
>>> /* CPPC specific PCC commands. */
>>> #define CMD_READ 0
>>> @@ -109,6 +111,8 @@ enum cppc_regs {
>>> REFERENCE_PERF,
>>> LOWEST_FREQ,
>>> NOMINAL_FREQ,
>>> + OSPM_NOMINAL_PERF,
>>> + RESOURCE_PRIORITY,
>>> };
>>>
>>> /*
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support
2026-04-27 5:18 ` [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support Sumit Gupta
@ 2026-04-27 15:36 ` Mario Limonciello
2026-04-28 12:55 ` Sumit Gupta
0 siblings, 1 reply; 10+ messages in thread
From: Mario Limonciello @ 2026-04-27 15:36 UTC (permalink / raw)
To: Sumit Gupta, rafael, viresh.kumar, lenb, pierre.gondois,
zhenglifeng1, zhanjie9, saket.dumbre, linux-acpi, linux-kernel,
linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu
On 4/27/26 00:18, Sumit Gupta wrote:
> Add acpi_cppc/ospm_nominal_perf sysfs attribute (write-only) and
> cppc_set_ospm_nominal_perf() API for the OSPM Nominal Performance
> register (ACPI 6.6, Section 8.4.6.1.2.6).
>
> The register conveys the desired nominal performance level at which
> the platform may run. OSPM can request a lower level than platform
> nominal. Valid range is [Lowest Performance, Nominal Performance].
> The value tells the platform what OSPM considers nominal. The
> platform classifies performance above this as boosted and below as
> throttled. It uses that for its power/thermal decisions.
>
> Initialize to platform nominal at policy init. Override via sysfs
> if needed.
>
> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
Even though it's a write only register; does it make sense to be a write
only sysfs file?
I say this because if we're writing it at init time and we're the OSPM
we should be able to track the state of what we wrote and display that
to userspace if it wants to know.
Furthermore; tracking the state could mean store_ospm_nominal_perf() can
avoid the extra register write if the state we tracked is the same
userspace tried to write.
> ---
> drivers/acpi/cppc_acpi.c | 42 ++++++++++++++++++++++++++++++++++
> drivers/cpufreq/cppc_cpufreq.c | 10 ++++++++
> include/acpi/cppc_acpi.h | 5 ++++
> 3 files changed, 57 insertions(+)
>
> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
> index a1c91ce20cc8..83b4b14652fb 100644
> --- a/drivers/acpi/cppc_acpi.c
> +++ b/drivers/acpi/cppc_acpi.c
> @@ -155,6 +155,10 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
> static struct kobj_attribute _name = \
> __ATTR(_name, 0444, show_##_name, NULL)
>
> +#define define_one_cppc_wo(_name) \
> +static struct kobj_attribute _name = \
> +__ATTR(_name, 0200, NULL, store_##_name)
> +
> #define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj)
>
> #define show_cppc_data(access_fn, struct_name, member_name) \
> @@ -211,6 +215,26 @@ static ssize_t show_feedback_ctrs(struct kobject *kobj,
> }
> define_one_cppc_ro(feedback_ctrs);
>
> +static ssize_t store_ospm_nominal_perf(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
> + u64 val;
> + int ret;
> +
> + ret = kstrtou64(buf, 0, &val);
> + if (ret)
> + return ret;
> +
> + ret = cppc_set_ospm_nominal_perf(cpc_ptr->cpu_id, val);
> + if (ret)
> + return ret;
> +
> + return count;
> +}
> +define_one_cppc_wo(ospm_nominal_perf);
> +
> static struct attribute *cppc_attrs[] = {
> &feedback_ctrs.attr,
> &reference_perf.attr,
> @@ -222,6 +246,7 @@ static struct attribute *cppc_attrs[] = {
> &nominal_perf.attr,
> &nominal_freq.attr,
> &lowest_freq.attr,
> + &ospm_nominal_perf.attr,
> NULL
> };
> ATTRIBUTE_GROUPS(cppc);
> @@ -1683,6 +1708,23 @@ int cppc_set_epp(int cpu, u64 epp_val)
> }
> EXPORT_SYMBOL_GPL(cppc_set_epp);
>
> +/**
> + * cppc_set_ospm_nominal_perf() - Write OSPM Nominal Performance register.
> + * @cpu: CPU on which to write register.
> + * @ospm_nominal_perf: Value to write to the OSPM Nominal Performance register.
> + *
> + * OSPM Nominal Performance allows OSPM to inform the platform of the nominal
> + * performance level it intends to maintain. This is a write-only register per
> + * ACPI specification.
> + *
> + * Return: 0 for success, -EOPNOTSUPP if not supported, -EIO otherwise.
> + */
> +int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf)
> +{
> + return cppc_set_reg_val(cpu, OSPM_NOMINAL_PERF, ospm_nominal_perf);
> +}
> +EXPORT_SYMBOL_GPL(cppc_set_ospm_nominal_perf);
> +
> /**
> * cppc_get_auto_act_window() - Read autonomous activity window register.
> * @cpu: CPU from which to read register.
> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
> index 7e7f9dfb7a24..d06cba963550 100644
> --- a/drivers/cpufreq/cppc_cpufreq.c
> +++ b/drivers/cpufreq/cppc_cpufreq.c
> @@ -715,6 +715,16 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
> goto out;
> }
>
> + /*
> + * Initialize OSPM Nominal Performance to inform firmware of
> + * OSPM's nominal level. Performance above this value = boost;
> + * below = throttle. Uses platform nominal by default.
> + */
> + ret = cppc_set_ospm_nominal_perf(cpu, caps->nominal_perf);
> + if (ret && ret != -EOPNOTSUPP)
> + pr_debug("Failed to set ospm_nominal_perf for CPU%d: %d\n",
> + cpu, ret);
> +
> cppc_cpufreq_cpu_fie_init(policy);
> return 0;
>
> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
> index 8693890a7275..ad1035b0e1de 100644
> --- a/include/acpi/cppc_acpi.h
> +++ b/include/acpi/cppc_acpi.h
> @@ -180,6 +180,7 @@ extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
> extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf);
> extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable);
> extern int cppc_set_epp(int cpu, u64 epp_val);
> +extern int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf);
> extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window);
> extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window);
> extern int cppc_get_auto_sel(int cpu, bool *enable);
> @@ -266,6 +267,10 @@ static inline int cppc_set_epp(int cpu, u64 epp_val)
> {
> return -EOPNOTSUPP;
> }
> +static inline int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf)
> +{
> + return -EOPNOTSUPP;
> +}
> static inline int cppc_get_auto_act_window(int cpu, u64 *auto_act_window)
> {
> return -EOPNOTSUPP;
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
2026-04-27 5:18 ` [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4 Sumit Gupta
2026-04-27 7:06 ` zhenglifeng (A)
@ 2026-04-27 15:37 ` Mario Limonciello
1 sibling, 0 replies; 10+ messages in thread
From: Mario Limonciello @ 2026-04-27 15:37 UTC (permalink / raw)
To: Sumit Gupta, rafael, viresh.kumar, lenb, pierre.gondois,
zhenglifeng1, zhanjie9, saket.dumbre, linux-acpi, linux-kernel,
linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu
On 4/27/26 00:18, Sumit Gupta wrote:
> CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
> _CPC package:
>
> 1. OSPM Nominal Performance (8.4.6.1.2.6): A write-only register that
> lets OSPM inform the platform what it considers nominal performance.
> The platform classifies performance above this level as boost and
> below as throttle for its power/thermal decisions.
>
> 2. Resource Priority (8.4.6.1.2.7): A Package of Resource Priority
> Register Descriptor sub-packages that allow OSPM to set relative
> priority among processors for shared resources (boost, throttle,
> L2/L3 cache, memory bandwidth). Parsing the full structure is not
> yet supported; such entries are marked as unsupported.
>
> Add v4 _CPC table parsing (25 entries) and update REG_OPTIONAL to
> mark the two new registers as optional.
>
> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
> ---
> drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------
> include/acpi/cppc_acpi.h | 8 ++++++--
> 2 files changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
> index 2e91c5a97761..a1c91ce20cc8 100644
> --- a/drivers/acpi/cppc_acpi.c
> +++ b/drivers/acpi/cppc_acpi.c
> @@ -134,7 +134,7 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
> * cpc_regs[] with the corresponding index. 0 means mandatory and 1
> * means optional.
> */
> -#define REG_OPTIONAL (0x1FC7D0)
> +#define REG_OPTIONAL (0x7FC7D0)
>
> /*
> * Use the index of the register in per-cpu cpc_regs[] to check if
> @@ -751,18 +751,19 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
> /*
> * Disregard _CPC if the number of entries in the return package is not
> * as expected, but support future revisions being proper supersets of
> - * the v3 and only causing more entries to be returned by _CPC.
> + * the v4 and only causing more entries to be returned by _CPC.
> */
> if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) ||
> (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) ||
> - (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) {
> + (cpc_rev == CPPC_V4_REV && num_ent != CPPC_V4_NUM_ENT) ||
> + (cpc_rev > CPPC_V4_REV && num_ent <= CPPC_V4_NUM_ENT)) {
> pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n",
> num_ent, pr->id);
> goto out_free;
> }
> - if (cpc_rev > CPPC_V3_REV) {
> - num_ent = CPPC_V3_NUM_ENT;
> - cpc_rev = CPPC_V3_REV;
> + if (cpc_rev > CPPC_V4_REV) {
> + num_ent = CPPC_V4_NUM_ENT;
> + cpc_rev = CPPC_V4_REV;
> }
>
> cpc_ptr->num_entries = num_ent;
> @@ -845,6 +846,17 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
>
> cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
> memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
> + } else if (cpc_obj->type == ACPI_TYPE_PACKAGE) {
> + /*
> + * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority
> + * as a Package of Resource Priority Register Descriptor
> + * sub-packages. Parsing the full structure is not yet
> + * supported; mark the register as unsupported for now.
> + */
> + pr_debug("CPU:%d entry %d: package type not supported\n",
> + pr->id, i);
> + cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
> + cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = 0;
> } else {
> pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n",
> i, pr->id);
> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
> index d1f02ceec4f9..8693890a7275 100644
> --- a/include/acpi/cppc_acpi.h
> +++ b/include/acpi/cppc_acpi.h
> @@ -17,16 +17,18 @@
> #include <acpi/pcc.h>
> #include <acpi/processor.h>
>
> -/* CPPCv2 and CPPCv3 support */
> +/* CPPCv2, CPPCv3 and CPPCv4 support */
> #define CPPC_V2_REV 2
> #define CPPC_V3_REV 3
> +#define CPPC_V4_REV 4
> #define CPPC_V2_NUM_ENT 21
> #define CPPC_V3_NUM_ENT 23
> +#define CPPC_V4_NUM_ENT 25
>
> #define PCC_CMD_COMPLETE_MASK (1 << 0)
> #define PCC_ERROR_MASK (1 << 2)
>
> -#define MAX_CPC_REG_ENT 21
> +#define MAX_CPC_REG_ENT 23
>
> /* CPPC specific PCC commands. */
> #define CMD_READ 0
> @@ -109,6 +111,8 @@ enum cppc_regs {
> REFERENCE_PERF,
> LOWEST_FREQ,
> NOMINAL_FREQ,
> + OSPM_NOMINAL_PERF,
> + RESOURCE_PRIORITY,
> };
>
> /*
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
2026-04-27 15:33 ` Mario Limonciello
@ 2026-04-28 12:53 ` Sumit Gupta
0 siblings, 0 replies; 10+ messages in thread
From: Sumit Gupta @ 2026-04-28 12:53 UTC (permalink / raw)
To: Mario Limonciello, zhenglifeng (A), rafael, viresh.kumar, lenb,
pierre.gondois, zhanjie9, saket.dumbre, linux-acpi, linux-kernel,
linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu
On 27/04/26 21:03, Mario Limonciello wrote:
> External email: Use caution opening links or attachments
>
>
> On 4/27/26 03:04, Sumit Gupta wrote:
>>
>> On 27/04/26 12:36, zhenglifeng (A) wrote:
>>> External email: Use caution opening links or attachments
>>>
>>>
>>> It seems that mario has sent a similar patch:
>>>
>>> https://lore.kernel.org/all/20260427035520.1427080-3-superm1@kernel.org/
>>>
>>
>>
>> Thank you for sharing.
>> Yes, both look similar with below two change.
>> 1. REG_OPTIONAL needs the 0x1FC7D0 -> 0x7FC7D0 update to mark
>> the two new registers optional. This is present in my [PATCH 1/2].
>> 2. For Resource Priority, pkg_data added to cpc_entry.
>> This is present in Mario's [PATCH 2/6].
>>
>>
>> Hi Mario,
>> How would you like to proceed? A few options:
>> (a) Let both CPPCv4 patches from this series go separately.
>> (b) Fold the REG_OPTIONAL update from my patch 1/2 into your
>> patch, and pull my patch 2/2 into your series.
>> (c) Anything else you'd prefer.
>> Either way works for me.
>>
>> Thank you,
>> Sumit Gupta
>>
>
>
> Reviewing yours points out that I totally missed updating REG_OPTIONAL
> with the two new ACPI 6.7 fields being optional too.
>
> In my series I only add in CPPv4 so I can build on top of the changes
> for CPPCv5.
>
> So - I would say we should let your patches merge for v4 and I'll drop
> the relevant ones from my series and rebase mine on top of your work.
>
Thanks Mario.
I will proceed with this series and add your Reviewed-by to this patch
in v2.
Thank you,
Sumit Gupta
>
>>
>>>
>>> On 4/27/2026 1:18 PM, Sumit Gupta wrote:
>>>> CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
>>>> _CPC package:
>>>>
>>>> 1. OSPM Nominal Performance (8.4.6.1.2.6): A write-only register that
>>>> lets OSPM inform the platform what it considers nominal
>>>> performance.
>>>> The platform classifies performance above this level as boost and
>>>> below as throttle for its power/thermal decisions.
>>>>
>>>> 2. Resource Priority (8.4.6.1.2.7): A Package of Resource Priority
>>>> Register Descriptor sub-packages that allow OSPM to set relative
>>>> priority among processors for shared resources (boost, throttle,
>>>> L2/L3 cache, memory bandwidth). Parsing the full structure is not
>>>> yet supported; such entries are marked as unsupported.
>>>>
>>>> Add v4 _CPC table parsing (25 entries) and update REG_OPTIONAL to
>>>> mark the two new registers as optional.
>>>>
>>>> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
>>>> ---
....
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support
2026-04-27 15:36 ` Mario Limonciello
@ 2026-04-28 12:55 ` Sumit Gupta
0 siblings, 0 replies; 10+ messages in thread
From: Sumit Gupta @ 2026-04-28 12:55 UTC (permalink / raw)
To: Mario Limonciello, rafael, viresh.kumar, lenb, pierre.gondois,
zhenglifeng1, zhanjie9, saket.dumbre, linux-acpi, linux-kernel,
linux-pm, acpica-devel
Cc: treding, jonathanh, vsethi, ksitaraman, sanjayc, bbasu
On 27/04/26 21:06, Mario Limonciello wrote:
> External email: Use caution opening links or attachments
>
>
> On 4/27/26 00:18, Sumit Gupta wrote:
>> Add acpi_cppc/ospm_nominal_perf sysfs attribute (write-only) and
>> cppc_set_ospm_nominal_perf() API for the OSPM Nominal Performance
>> register (ACPI 6.6, Section 8.4.6.1.2.6).
>>
>> The register conveys the desired nominal performance level at which
>> the platform may run. OSPM can request a lower level than platform
>> nominal. Valid range is [Lowest Performance, Nominal Performance].
>> The value tells the platform what OSPM considers nominal. The
>> platform classifies performance above this as boosted and below as
>> throttled. It uses that for its power/thermal decisions.
>>
>> Initialize to platform nominal at policy init. Override via sysfs
>> if needed.
>>
>> Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
>
> Even though it's a write only register; does it make sense to be a write
> only sysfs file?
>
> I say this because if we're writing it at init time and we're the OSPM
> we should be able to track the state of what we wrote and display that
> to userspace if it wants to know.
>
> Furthermore; tracking the state could mean store_ospm_nominal_perf() can
> avoid the extra register write if the state we tracked is the same
> userspace tried to write.
Agreed. Will update in v2 to:
- Make sysfs attribute rw.
- Cache the value in cpc_desc and skip register write when unchanged.
- Have show return the cached value.
Thank you,
Sumit Gupta
>
>> ---
>> drivers/acpi/cppc_acpi.c | 42 ++++++++++++++++++++++++++++++++++
>> drivers/cpufreq/cppc_cpufreq.c | 10 ++++++++
>> include/acpi/cppc_acpi.h | 5 ++++
>> 3 files changed, 57 insertions(+)
>>
>> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
>> index a1c91ce20cc8..83b4b14652fb 100644
>> --- a/drivers/acpi/cppc_acpi.c
>> +++ b/drivers/acpi/cppc_acpi.c
>> @@ -155,6 +155,10 @@ static DEFINE_PER_CPU(struct cpc_desc *,
>> cpc_desc_ptr);
>> static struct kobj_attribute _name = \
>> __ATTR(_name, 0444, show_##_name, NULL)
>>
>> +#define define_one_cppc_wo(_name) \
>> +static struct kobj_attribute _name = \
>> +__ATTR(_name, 0200, NULL, store_##_name)
>> +
>> #define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj)
>>
>> #define show_cppc_data(access_fn, struct_name, member_name) \
>> @@ -211,6 +215,26 @@ static ssize_t show_feedback_ctrs(struct kobject
>> *kobj,
>> }
>> define_one_cppc_ro(feedback_ctrs);
>>
>> +static ssize_t store_ospm_nominal_perf(struct kobject *kobj,
>> + struct kobj_attribute *attr,
>> + const char *buf, size_t count)
>> +{
>> + struct cpc_desc *cpc_ptr = to_cpc_desc(kobj);
>> + u64 val;
>> + int ret;
>> +
>> + ret = kstrtou64(buf, 0, &val);
>> + if (ret)
>> + return ret;
>> +
>> + ret = cppc_set_ospm_nominal_perf(cpc_ptr->cpu_id, val);
>> + if (ret)
>> + return ret;
>> +
>> + return count;
>> +}
>> +define_one_cppc_wo(ospm_nominal_perf);
>> +
>> static struct attribute *cppc_attrs[] = {
>> &feedback_ctrs.attr,
>> &reference_perf.attr,
>> @@ -222,6 +246,7 @@ static struct attribute *cppc_attrs[] = {
>> &nominal_perf.attr,
>> &nominal_freq.attr,
>> &lowest_freq.attr,
>> + &ospm_nominal_perf.attr,
>> NULL
>> };
>> ATTRIBUTE_GROUPS(cppc);
>> @@ -1683,6 +1708,23 @@ int cppc_set_epp(int cpu, u64 epp_val)
>> }
>> EXPORT_SYMBOL_GPL(cppc_set_epp);
>>
>> +/**
>> + * cppc_set_ospm_nominal_perf() - Write OSPM Nominal Performance
>> register.
>> + * @cpu: CPU on which to write register.
>> + * @ospm_nominal_perf: Value to write to the OSPM Nominal
>> Performance register.
>> + *
>> + * OSPM Nominal Performance allows OSPM to inform the platform of
>> the nominal
>> + * performance level it intends to maintain. This is a write-only
>> register per
>> + * ACPI specification.
>> + *
>> + * Return: 0 for success, -EOPNOTSUPP if not supported, -EIO otherwise.
>> + */
>> +int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf)
>> +{
>> + return cppc_set_reg_val(cpu, OSPM_NOMINAL_PERF,
>> ospm_nominal_perf);
>> +}
>> +EXPORT_SYMBOL_GPL(cppc_set_ospm_nominal_perf);
>> +
>> /**
>> * cppc_get_auto_act_window() - Read autonomous activity window
>> register.
>> * @cpu: CPU from which to read register.
>> diff --git a/drivers/cpufreq/cppc_cpufreq.c
>> b/drivers/cpufreq/cppc_cpufreq.c
>> index 7e7f9dfb7a24..d06cba963550 100644
>> --- a/drivers/cpufreq/cppc_cpufreq.c
>> +++ b/drivers/cpufreq/cppc_cpufreq.c
>> @@ -715,6 +715,16 @@ static int cppc_cpufreq_cpu_init(struct
>> cpufreq_policy *policy)
>> goto out;
>> }
>>
>> + /*
>> + * Initialize OSPM Nominal Performance to inform firmware of
>> + * OSPM's nominal level. Performance above this value = boost;
>> + * below = throttle. Uses platform nominal by default.
>> + */
>> + ret = cppc_set_ospm_nominal_perf(cpu, caps->nominal_perf);
>> + if (ret && ret != -EOPNOTSUPP)
>> + pr_debug("Failed to set ospm_nominal_perf for CPU%d:
>> %d\n",
>> + cpu, ret);
>> +
>> cppc_cpufreq_cpu_fie_init(policy);
>> return 0;
>>
>> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
>> index 8693890a7275..ad1035b0e1de 100644
>> --- a/include/acpi/cppc_acpi.h
>> +++ b/include/acpi/cppc_acpi.h
>> @@ -180,6 +180,7 @@ extern int cpc_write_ffh(int cpunum, struct
>> cpc_reg *reg, u64 val);
>> extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf);
>> extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls
>> *perf_ctrls, bool enable);
>> extern int cppc_set_epp(int cpu, u64 epp_val);
>> +extern int cppc_set_ospm_nominal_perf(int cpu, u64 ospm_nominal_perf);
>> extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window);
>> extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window);
>> extern int cppc_get_auto_sel(int cpu, bool *enable);
>> @@ -266,6 +267,10 @@ static inline int cppc_set_epp(int cpu, u64
>> epp_val)
>> {
>> return -EOPNOTSUPP;
>> }
>> +static inline int cppc_set_ospm_nominal_perf(int cpu, u64
>> ospm_nominal_perf)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> static inline int cppc_get_auto_act_window(int cpu, u64
>> *auto_act_window)
>> {
>> return -EOPNOTSUPP;
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-04-28 12:56 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 5:18 [PATCH 0/2] ACPI: CPPC: Add CPPC v4 support (ACPI 6.6) Sumit Gupta
2026-04-27 5:18 ` [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4 Sumit Gupta
2026-04-27 7:06 ` zhenglifeng (A)
2026-04-27 8:04 ` Sumit Gupta
2026-04-27 15:33 ` Mario Limonciello
2026-04-28 12:53 ` Sumit Gupta
2026-04-27 15:37 ` Mario Limonciello
2026-04-27 5:18 ` [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support Sumit Gupta
2026-04-27 15:36 ` Mario Limonciello
2026-04-28 12:55 ` Sumit Gupta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox