| // 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"); |
| } |