ACPI: CPPC: Add CPPC v4 support (ACPI 6.6)
Subsystems (5)
Sumit Gupta
reviewercover ACPI: CPPC: Add CPPC v4 support (ACPI 6.6)
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(-)
Signature · 1 line
2.34.1
Sumit Gupta
reviewerPATCH 1/2 ACPI: CPPC: Add support for CPPC v4
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.
--- drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------ include/acpi/cppc_acpi.h | 8 ++++++-- 2 files changed, 24 insertions(+), 8 deletions(-)
drivers/acpi/cppc_acpi.c +18 -6
@@ -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);
include/acpi/cppc_acpi.h +6 -2
@@ -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, };/*
Signature · 1 line
2.34.1
zhenglifeng (A)
reviewerRe: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
It seems that mario has sent a similar patch:
https://lore.kernel.org/all/[email protected]/
Quoted 113 lines · Sumit Gupta
CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
_CPCpackage: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
_CPCtable parsing (25 entries) and updateREG_OPTIONALto mark the two new registers as optional.Signed-off-by Sumit Gupta <[email protected]>--- drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------ include/acpi/cppc_acpi.h | 8 ++++++-- 2 files changed, 24 insertions(+), 8 deletions(-)drivers/acpi/cppc_acpi.c +18
-6@@ -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);include/acpi/cppc_acpi.h +6
-2@@ -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, };/*
Sumit Gupta
reviewerRe: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
Quoted 6 lines · zhenglifeng (A)
External email: Use caution opening links or attachments
It seems that mario has sent a similar patch:
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
Quoted 115 lines · Sumit Gupta
Quoted 113 lines
CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
_CPCpackage: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
_CPCtable parsing (25 entries) and updateREG_OPTIONALto mark the two new registers as optional.Signed-off-by Sumit Gupta <[email protected]>--- drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------ include/acpi/cppc_acpi.h | 8 ++++++-- 2 files changed, 24 insertions(+), 8 deletions(-)drivers/acpi/cppc_acpi.c +18
-6@@ -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);include/acpi/cppc_acpi.h +6
-2@@ -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, };/*
Re: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
Quoted 26 lines · Sumit Gupta
Quoted 6 lines · zhenglifeng (A)
External email: Use caution opening links or attachments
It seems that mario has sent a similar patch:
Thank you for sharing.
Yes, both look similar with below two change.
1.REG_OPTIONALneeds the0x1FC7D0->0x7FC7D0update to mark the two new registers optional. This is present in my [PATCH 1/2].
2. For Resource Priority,pkg_dataadded tocpc_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 theREG_OPTIONALupdate 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.
Quoted 3 lines
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.
Quoted 124 lines
Quoted 124 lines · Sumit Gupta
Quoted 121 lines
CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
_CPCpackage: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
_CPCtable parsing (25 entries) and updateREG_OPTIONALto mark the two new registers as optional.Signed-off-by Sumit Gupta <[email protected]>---
drivers/acpi/cppc_acpi.c| 24 ++++++++++++++++++------include/acpi/cppc_acpi.h| 8 ++++++--2 files changed, 24 insertions(+), 8 deletions(-)drivers/acpi/cppc_acpi.c +1
-1@@ -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
drivers/acpi/cppc_acpi.c +1
-1@@ -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);
gotoout_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;drivers/acpi/cppc_acpi.c +3
-0@@ -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);include/acpi/cppc_acpi.h +6
-2@@ -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, }; /*
Sumit Gupta
reviewerRe: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
Quoted 36 lines · Mario Limonciello
External email: Use caution opening links or attachments
Quoted 27 lines · Sumit Gupta
Quoted 7 lines · zhenglifeng (A)
External email: Use caution opening links or attachments
It seems that mario has sent a similar patch:
Thank you for sharing.
Yes, both look similar with below two change.
1.REG_OPTIONALneeds the0x1FC7D0->0x7FC7D0update to mark the two new registers optional. This is present in my [PATCH 1/2].
2. For Resource Priority,pkg_dataadded tocpc_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 theREG_OPTIONALupdate 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.Quoted 3 lines
Thank you,
Sumit Gupta
Quoted 9 lines
Reviewing yours points out that I totally missed updating
REG_OPTIONALwith 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
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines · Sumit Gupta
Quoted 19 lines
CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
_CPCpackage: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
_CPCtable parsing (25 entries) and updateREG_OPTIONALto mark the two new registers as optional.Signed-off-by Sumit Gupta <[email protected]>---
....
Re: [PATCH 1/2] ACPI: CPPC: Add support for CPPC v4
In reply to Sumit GuptaQuoted 14 lines · Sumit Gupta
CPPC v4 (ACPI 6.6, Section 8.4.6) adds two optional entries to the
_CPCpackage: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.
Quoted 4 lines
Add v4
_CPCtable parsing (25 entries) and updateREG_OPTIONALto mark the two new registers as optional.Signed-off-by Sumit Gupta <[email protected]>
Quoted 95 lines
--- drivers/acpi/cppc_acpi.c | 24 ++++++++++++++++++------ include/acpi/cppc_acpi.h | 8 ++++++-- 2 files changed, 24 insertions(+), 8 deletions(-)drivers/acpi/cppc_acpi.c +18
-6@@ -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);include/acpi/cppc_acpi.h +6
-2@@ -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, };/*
Sumit Gupta
reviewerPATCH 2/2 ACPI: CPPC: Add ospm_nominal_perf support
In reply to Sumit GuptaAdd 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.
--- drivers/acpi/cppc_acpi.c | 42 ++++++++++++++++++++++++++++++++++ drivers/cpufreq/cppc_cpufreq.c | 10 ++++++++ include/acpi/cppc_acpi.h | 5 ++++ 3 files changed, 57 insertions(+)
drivers/acpi/cppc_acpi.c +42 -0
@@ -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.
drivers/cpufreq/cppc_cpufreq.c +10 -0
@@ -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 ;
include/acpi/cppc_acpi.h +5 -0
@@ -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 ;
Signature · 1 line
2.34.1
Re: [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support
Quoted 11 lines · Sumit Gupta
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.
Quoted 4 lines
Initialize to platform nominal at policy init. Override via sysfs if needed.
Signed-off-by Sumit Gupta <[email protected]>
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.
Quoted 124 lines
--- drivers/acpi/cppc_acpi.c | 42 ++++++++++++++++++++++++++++++++++ drivers/cpufreq/cppc_cpufreq.c | 10 ++++++++ include/acpi/cppc_acpi.h | 5 ++++ 3 files changed, 57 insertions(+)drivers/acpi/cppc_acpi.c +42
-0@@ -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. drivers/cpufreq/cppc_cpufreq.c +10
-0@@ -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 ;include/acpi/cppc_acpi.h +5
-0@@ -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 ;
Sumit Gupta
reviewerRe: [PATCH 2/2] ACPI: CPPC: Add ospm_nominal_perf support
Quoted 23 lines · Mario Limonciello
External email: Use caution opening links or attachments
Quoted 11 lines · Sumit Gupta
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.
Quoted 4 lines
Initialize to platform nominal at policy init. Override via sysfs if needed.
Signed-off-by Sumit Gupta <[email protected]>Even though it's a write only register; does it make sense to be a write only sysfs file?
Quoted 7 lines
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
Quoted 138 lines
Quoted 137 lines
---
drivers/acpi/cppc_acpi.c | 42 ++++++++++++++++++++++++++++++++++drivers/cpufreq/cppc_cpufreq.c| 10 ++++++++ include/acpi/cppc_acpi.h | 5 ++++3 files changed, 57 insertions(+)drivers/acpi/cppc_acpi.c +4
-0@@ -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)\drivers/acpi/cppc_acpi.c +20
-0@@ -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,
drivers/acpi/cppc_acpi.c +1
-0@@ -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);drivers/acpi/cppc_acpi.c +2
-0@@ -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,-EOPNOTSUPPif not supported,-EIOotherwise.
+ */drivers/acpi/cppc_acpi.c +3
-0+int cppc_set_ospm_nominal_perf (int cpu,u64 ospm_nominal_perf) +{ + return cppc_set_reg_val(cpu, OSPM_NOMINAL_PERF,
ospm_nominal_perf);drivers/acpi/cppc_acpi.c +3
-0+} +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.drivers/cpufreq/cppc_cpufreq.c +10
-0@@ -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;
include/acpi/cppc_acpi.h +1
-0@@ -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);include/acpi/cppc_acpi.h +4
-0@@ -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;