diff --git a/tools/power/cpupower/utils/helpers/cppc.c b/tools/power/cpupower/utils/helpers/cppc.c new file mode 100644 index 000000000000..3493ce8551ea --- /dev/null +++ b/tools/power/cpupower/utils/helpers/cppc.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#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"); +}