mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 02:53:16 -04:00
cpupower: Add generic CPPC performance display
Arm64 machines, and possibly others, use the standard ACPI defined CPPC infrastructure. cpupower has CPPC support, but it's largely written around the intricacies of AMD processors, using platform MSRs to avoid shortcomings in the specification. Add a generic CPPC display that depends only on standardized fields. The computed frequency values are best effort and rely on the FW providing optional values that can be used to derive a meaningful frequency at a given unique performance level. Link: https://lore.kernel.org/r/20260709221344.1919794-2-jeremy.linton@arm.com Signed-off-by: Jeremy Linton <jeremy.linton@arm.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
This commit is contained in:
committed by
Shuah Khan
parent
dc59e4fea9
commit
68f34fad76
56
tools/power/cpupower/utils/helpers/cppc.c
Normal file
56
tools/power/cpupower/utils/helpers/cppc.c
Normal file
@@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "helpers/helpers.h"
|
||||
#include "cpufreq.h"
|
||||
#include "acpi_cppc.h"
|
||||
|
||||
#define cppc_to_frequency(perf) (roundf(slope * (perf) + intercept))
|
||||
|
||||
void cppc_show_perf_and_freq(unsigned int cpu, int no_rounding)
|
||||
{
|
||||
int64_t nominal = acpi_cppc_get_data(cpu, NOMINAL_PERF);
|
||||
int64_t nominal_freq = acpi_cppc_get_data(cpu, NOMINAL_FREQ) * 1000;
|
||||
int64_t lowest = acpi_cppc_get_data(cpu, LOWEST_PERF);
|
||||
int64_t lowest_freq = acpi_cppc_get_data(cpu, LOWEST_FREQ) * 1000;
|
||||
unsigned long non_linear = acpi_cppc_get_data(cpu, LOWEST_NONLINEAR_PERF);
|
||||
unsigned long highest = acpi_cppc_get_data(cpu, HIGHEST_PERF);
|
||||
float slope, intercept;
|
||||
|
||||
/* do the optional freq fields look invalid? */
|
||||
if (!nominal_freq || !lowest_freq || nominal == lowest)
|
||||
return;
|
||||
|
||||
slope = (float)(nominal_freq - lowest_freq) / (nominal - lowest);
|
||||
intercept = lowest_freq - slope * lowest;
|
||||
|
||||
printf(_(" CPPC limits:\n"));
|
||||
printf(_(" Highest Performance: %lu. Maximum Frequency: "),
|
||||
highest);
|
||||
/*
|
||||
* If boost isn't active, the cpuinfo_max doesn't indicate real max
|
||||
* frequency.
|
||||
*/
|
||||
print_speed(cppc_to_frequency(highest), no_rounding);
|
||||
printf(".\n");
|
||||
|
||||
printf(_(" Nominal Performance: %lu. Nominal Frequency: "),
|
||||
acpi_cppc_get_data(cpu, NOMINAL_PERF));
|
||||
print_speed(nominal_freq, no_rounding);
|
||||
printf(".\n");
|
||||
|
||||
printf(_(" Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "),
|
||||
non_linear);
|
||||
print_speed(cppc_to_frequency(non_linear), no_rounding);
|
||||
printf(".\n");
|
||||
|
||||
printf(_(" Lowest Performance: %lu. Lowest Frequency: "),
|
||||
acpi_cppc_get_data(cpu, LOWEST_PERF));
|
||||
print_speed(lowest_freq, no_rounding);
|
||||
printf(".\n");
|
||||
}
|
||||
Reference in New Issue
Block a user