[PATCH v7 1/3] ACPI: CPPC: Add ospm_nominal_perf support
Sumit Gupta <[email protected]> Sat, 8 Aug 2026 03:18:35 +0530
| Newsgroups | org.kernel.vger.linux-tegra,dev.linux.lists.acpica-devel,org.kernel.vger.linux-acpi,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm |
|---|---|
| Message-ID | <[email protected]> |
Expose the OSPM Nominal Performance register (ACPI 6.6, Section 8.4.6.1.2.6), which conveys the nominal performance level at which the platform may run. Unlike the read-only Nominal Performance register, it is writable, so OSPM can ask for a nominal level below the platform-reported one, which then becomes the boundary between boosted and throttled operation for the platform's power and thermal decisions. Add cppc_set_ospm_nominal_perf() to write the register. Per the spec, the value must lie in [Lowest Performance, Nominal Performance], which the caller is responsible for validating. Add cppc_ospm_nominal_perf_supported() to report whether the platform implements the register as writable, since a write-only register cannot be probed by reading it. Factor the writable-register check out of cppc_set_reg_val() into cpc_reg_writable() and use it for both, so support is never reported for a register that a write would reject. Signed-off-by: Sumit Gupta <[email protected]> --- drivers/acpi/cppc_acpi.c | 48 ++++++++++++++++++++++++++++++++++++++-- include/acpi/cppc_acpi.h | 10 +++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 9e882b3911e6..b6bf46cb06cb 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1388,6 +1388,13 @@ static int cppc_set_reg_val_in_pcc(int cpu, struct cpc_register_resource *reg, u return ret; } +/* If a register is writeable, it must be a buffer and not null */ +static bool cpc_reg_writable(const struct cpc_register_resource *reg) +{ + return reg->type == ACPI_TYPE_BUFFER && + !IS_NULL_REG(®->cpc_entry.reg); +} + static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val) { struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); @@ -1400,8 +1407,7 @@ static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val) reg = &cpc_desc->cpc_regs[reg_idx]; - /* if a register is writeable, it must be a buffer and not null */ - if ((reg->type != ACPI_TYPE_BUFFER) || IS_NULL_REG(®->cpc_entry.reg)) { + if (!cpc_reg_writable(reg)) { pr_debug("CPC register is not supported\n"); return -EOPNOTSUPP; } @@ -1832,6 +1838,44 @@ 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 conveys the desired nominal performance level + * at which the platform may run. Per ACPI 6.6, s8.4.6.1.2.6, the value + * must lie within [Lowest Performance, Nominal Performance] and may be + * set independently of Minimum, Maximum and Desired performance. The + * caller is responsible for validating the range. + * + * Return: 0 on success or negative error code. + */ +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_ospm_nominal_perf_supported() - Check OSPM Nominal Performance support. + * @cpu: CPU to query. + * + * The OSPM Nominal Performance register is write-only, so its value + * cannot be read back. This only reports whether the platform implements + * it as a writable register. + * + * Return: true if the register is supported, false otherwise. + */ +bool cppc_ospm_nominal_perf_supported(int cpu) +{ + struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); + + return cpc_desc && + cpc_reg_writable(&cpc_desc->cpc_regs[OSPM_NOMINAL_PERF]); +} +EXPORT_SYMBOL_GPL(cppc_ospm_nominal_perf_supported); + /** * cppc_get_auto_act_window() - Read autonomous activity window register. * @cpu: CPU from which to read register. diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 3394e1b208be..a078ad5964c2 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -185,6 +185,8 @@ 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 bool cppc_ospm_nominal_perf_supported(int cpu); 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, u64 *enable); @@ -277,6 +279,14 @@ 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 bool cppc_ospm_nominal_perf_supported(int cpu) +{ + return false; +} static inline int cppc_get_auto_act_window(int cpu, u64 *auto_act_window) { return -EOPNOTSUPP; -- 2.34.1