diff options
author | dragonn | 2021-10-02 18:39:30 +0200 |
---|---|---|
committer | dragonn | 2021-10-02 18:46:42 +0200 |
commit | 1a7d00bb70c5f03cf9ec04e6ab94ad47aa7be450 (patch) | |
tree | b4a3f38d9177d6b3a7fb3ef91ad184a72c01a16c /sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch | |
parent | 3fd8f33c94d648c87abfb4db970367cf6b6633a6 (diff) | |
download | aur-1a7d00bb70c5f03cf9ec04e6ab94ad47aa7be450.tar.gz |
update fan curve patch, 5.14.9, update media patches, tablet mode
Diffstat (limited to 'sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch')
-rw-r--r-- | sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch | 892 |
1 files changed, 562 insertions, 330 deletions
diff --git a/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch b/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch index 09471946e6f9..da19351fa6a8 100644 --- a/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch +++ b/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch @@ -1,11 +1,11 @@ -From 1cf7e7f39c0c1a259ffd8c58b69edfc933936913 Mon Sep 17 00:00:00 2001 +From e0aeb1b7aaf55f3550cac74057c0d850c6a8f24e Mon Sep 17 00:00:00 2001 From: Scott B <arglebargle@arglebargle.dev> -Date: Thu, 9 Sep 2021 18:02:09 -0700 -Subject: [PATCH] amd-pstate v1 +Date: Sun, 26 Sep 2021 11:02:58 -0700 +Subject: [PATCH] amd-pstate v2 Squashed commit of the following: -commit aee7d6c2aa9fde5120b03083676ad86bf293aeaa +commit 15a541d4c1406bad735799bc0d663ac8c8ed860f Author: Huang Rui <ray.huang@amd.com> Date: Thu Jun 10 23:40:18 2021 +0800 @@ -15,7 +15,7 @@ Date: Thu Jun 10 23:40:18 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit d5130811e36f5557e2678de2f612c2db00a5c719 +commit 556f332dc97bf90e2df72482fd1d078bd9206ab4 Author: Huang Rui <ray.huang@amd.com> Date: Thu Jun 10 23:48:03 2021 +0800 @@ -27,61 +27,95 @@ Date: Thu Jun 10 23:48:03 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 8c239cb8a6e3704a75ab4139fd275a7e17b336c6 +commit 8f775fa6057be3964ecdfe0616b15ac515dafc97 Author: Huang Rui <ray.huang@amd.com> -Date: Sun Jun 20 18:25:55 2021 +0800 +Date: Sun Sep 26 16:26:06 2021 +0800 - cpupower: add amd-pstate get data function to query the info + cpupower: move print_speed function into misc helper - Frequency-info needs an interface to query the current amd-pstate data. + The print_speed can be as a common function, and expose it into misc + helper header. Then it can be used on other helper files as well. Signed-off-by: Huang Rui <ray.huang@amd.com> -commit ce0b684f184fee1fba6b6e0ef4ae4506a0d275c1 +commit ecd25fc5e7776669011b06ec0142c42224e415fd Author: Huang Rui <ray.huang@amd.com> Date: Sun Jun 20 17:35:45 2021 +0800 cpupower: enable boost state support for amd-pstate module - The AMD P-state boost API is different from ACPI hardware P-states, so - implement the support for amd-pstate kernel module. + The legacy ACPI hardware P-States function has 3 P-States on ACPI table, + the CPU frequency only can be switched between the 3 P-States. While the + processor supports the boost state, it will have another boost state + that the frequency can be higher than P0 state, and the state can be + decoded by the function of decode_pstates() and read by + amd_pci_get_num_boost_states(). + + However, the new AMD P-States function is different than legacy ACPI + hardware P-State on AMD processors. That has a finer grain frequency + range between the highest and lowest frequency. And boost frequency is + actually the frequency which is mapped on highest performance ratio. The + similiar previous P0 frequency is mapped on nominal performance ratio. + If the highest performance on the processor is higher than nominal + performance, then we think the current processor supports the boost + state. And it uses amd_pstate_boost_init() to initialize boost for AMD + P-States function. Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 97f78342eb9bcecfe44ef5307941dea1051e3a75 +commit bdbc7ab476c821eadefa00b89e80f33439749bf6 Author: Huang Rui <ray.huang@amd.com> Date: Sun Jun 20 17:07:25 2021 +0800 - cpupower: add amd-pstate sysfs entries into libcpufreq + cpupower: add amd-pstate sysfs definition and access helper - These amd-pstate sysfs entries will be used on cpupower for amd-pstate - kernel module. + Introduce the marco definitions and access helper function for + amd-pstate sysfs interfaces such as each performance goals and frequency + levels in amd helper file. They will be used to read the sysfs attribute + from amd-pstate cpufreq driver for cpupower utilities. Signed-off-by: Huang Rui <ray.huang@amd.com> -commit d99ecc31f798a4025baaea72607246dadedefca0 +commit e8d0f2a79d9ea76c838bc253389c3642139ebf05 +Author: Huang Rui <ray.huang@amd.com> +Date: Sun Sep 26 10:55:53 2021 +0800 + + cpupower: add the function to get the sysfs value from specific table + + Expose the helper into cpufreq header, then cpufreq driver can use this + function to get the sysfs value if it has any specific sysfs interfaces. + + Signed-off-by: Huang Rui <ray.huang@amd.com> + +commit c084ef5a4583083d09812801fcc4f881b6b80102 Author: Huang Rui <ray.huang@amd.com> Date: Sun Jun 27 22:40:14 2021 +0800 cpupower: initial AMD P-state capability - If kernel enables AMD P-state, cpupower won't need to respond ACPI - hardware P-states function anymore. + If kernel starts the amd-pstate module, the cpupower will initial the + capability flag as CPUPOWER_CAP_AMD_PSTATE. And once amd-pstate + capability is set, it won't need to set legacy ACPI relative + capabilities anymore. Signed-off-by: Huang Rui <ray.huang@amd.com> -commit f766224ca2c54192b9e9abaa50ce58ef5e72670d +commit f531c849130c1104ad81232bcd03ab6e17f2661d Author: Huang Rui <ray.huang@amd.com> Date: Sun Jun 27 22:25:39 2021 +0800 cpupower: add the function to check amd-pstate enabled - Introduce the cpupower_amd_pstate_enabled() to check whether the kernel - mode enables amd-pstate. + The processor with amd-pstate function also supports legacy ACPI + hardware P-States feature as well. Once driver sets amd-pstate eanbled, + the processor will respond the finer grain amd-pstate feature instead of + legacy ACPI P-States. So it introduces the cpupower_amd_pstate_enabled() + to check whether the current kernel enables amd-pstate or acpi-cpufreq + module. Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 0eca00885d7ce1cf7c03b8999fce887c9bafc411 +commit 510b487ccfe71ab5c19e2d0ef624f8925f15f600 Author: Huang Rui <ray.huang@amd.com> Date: Mon Jun 14 22:52:01 2021 +0800 @@ -92,7 +126,7 @@ Date: Mon Jun 14 22:52:01 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 9a70d7b125cad2356910cbf04e476d53b458c786 +commit 4351bf1becc53385a8ea76ddef076a753062309b Author: Huang Rui <ray.huang@amd.com> Date: Sun Jun 20 15:01:08 2021 +0800 @@ -103,7 +137,7 @@ Date: Sun Jun 20 15:01:08 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 48c5ae9172d62b6a6a8220f27afeaf47408ebb66 +commit 264932a7ddbee32b36af09261cc921e67bcdc61d Author: Huang Rui <ray.huang@amd.com> Date: Sun Jun 20 13:26:01 2021 +0800 @@ -114,7 +148,7 @@ Date: Sun Jun 20 13:26:01 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 4d003338827eca88097f35fae6e3ec75566bc788 +commit 40fde676994657f0c27cffb192d43f52e8da1c3d Author: Huang Rui <ray.huang@amd.com> Date: Sat Jun 19 23:41:30 2021 +0800 @@ -125,7 +159,7 @@ Date: Sat Jun 19 23:41:30 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit e8aa42d8143a5c8b65a63de34cd38bdc6d70fd82 +commit 690f2eaa700abee63d31c17873deac058433125b Author: Huang Rui <ray.huang@amd.com> Date: Thu Jun 10 23:13:00 2021 +0800 @@ -136,7 +170,7 @@ Date: Thu Jun 10 23:13:00 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 1cb45daf02f2cad44457ccc237c9d74f60eec621 +commit c9876ed4e1b126300ae8eecb2c3db64b2d043f88 Author: Huang Rui <ray.huang@amd.com> Date: Thu Jun 10 20:24:00 2021 +0800 @@ -147,7 +181,7 @@ Date: Thu Jun 10 20:24:00 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 152251e4cc636f4748d308ac31089ae7fd4e09c9 +commit 668359efad049de2efaedffa4a94a029f6a24982 Author: Huang Rui <ray.huang@amd.com> Date: Mon Aug 9 19:06:51 2021 +0800 @@ -159,7 +193,7 @@ Date: Mon Aug 9 19:06:51 2021 +0800 Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com> Signed-off-by: Huang Rui <ray.huang@amd.com> -commit a2a9f14e19c4b34986e6410dd4f430449a32d2a3 +commit 735f6c6664e3da48e67b44a6a59f9fa4b82c576d Author: Huang Rui <ray.huang@amd.com> Date: Fri Aug 13 18:43:47 2021 +0800 @@ -171,7 +205,7 @@ Date: Fri Aug 13 18:43:47 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit ffb5347387a6a070554d2e6f6af918ffbf1965c4 +commit ecab8f33c0660e9c96c42a5c27078a324185d601 Author: Huang Rui <ray.huang@amd.com> Date: Thu Jun 10 18:04:45 2021 +0800 @@ -287,18 +321,39 @@ Date: Thu Jun 10 18:04:45 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 5648469cb7cd30bc5bbd460b362c09223bdec3e5 +commit 47c390a1770904355262aef37bc25f0cee3cc3fc Author: Jinzhou Su <Jinzhou.Su@amd.com> Date: Mon Aug 9 19:04:17 2021 +0800 ACPI: CPPC: add cppc enable register function - Export the cppc enable register function for future use. + Add a new function to enable CPPC feature. This function + will write Continuous Performance Control package + EnableRegister field on the processor. Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com> Signed-off-by: Huang Rui <ray.huang@amd.com> -commit a0f215fdf3e24f2a74aa767cb5faef008ca3881e +commit 3b19018de66c74ed41fa6b9241fa5cffbbade6b2 +Author: Mario Limonciello <mario.limonciello@amd.com> +Date: Wed Jul 28 05:48:34 2021 +0800 + + ACPI: CPPC: Check online CPUs for determining _CPC is valid + + As this is a static check, it should be based upon what is currently + present on the system. This makes probeing more deterministic. + + While local APIC flags field (lapic_flags) of cpu core in MADT table is + 0, then the cpu core won't be enabled. In this case, _CPC won't be found + in this core, and return back to _CPC invalid with walking through + possible cpus (include disable cpus). This is not expected, so switch to + check online CPUs instead. + + Reported-by: Jinzhou Su <Jinzhou.Su@amd.com> + Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> + Signed-off-by: Huang Rui <ray.huang@amd.com> + +commit 2ab6419bfa88161ec5cf0ff45681923c793d9eff Author: Huang Rui <ray.huang@amd.com> Date: Mon Jan 25 15:50:24 2021 +0800 @@ -310,35 +365,42 @@ Date: Mon Jan 25 15:50:24 2021 +0800 Signed-off-by: Huang Rui <ray.huang@amd.com> -commit 1bff64e92f53c19784369a0cc1b7a05c918ed941 +commit 1993446c3c798df5946f0717122f545dd8f1278d Author: Huang Rui <ray.huang@amd.com> Date: Thu Jan 28 10:50:26 2021 +0800 - x86/cpufreatures: add AMD CPPC extension feature flag + x86/cpufreatures: add AMD Collaborative Processor Performance Control feature flag + + Add Collaborative Processor Performance Control feature flag for AMD + processors. - Add Collaborative Processor Performance Control Extension feature flag - for AMD processors. + This feature flag will be used on the following amd-pstate driver. The + amd-pstate driver has two approaches to implement the frequency control + behavior. That depends on the CPU hardware implementation. One is "Full + MSR Support" and another is "Shared Memory Support". The feature flag + indicates the current processors with "Full MSR Support". Signed-off-by: Huang Rui <ray.huang@amd.com> --- - Documentation/admin-guide/pm/amd_pstate.rst | 377 ++++++++ + Documentation/admin-guide/pm/amd_pstate.rst | 377 +++++++++ .../admin-guide/pm/working-state.rst | 1 + arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/msr-index.h | 17 + - drivers/acpi/cppc_acpi.c | 42 + + drivers/acpi/cppc_acpi.c | 50 +- drivers/cpufreq/Kconfig.x86 | 13 + drivers/cpufreq/Makefile | 5 + drivers/cpufreq/amd-pstate-trace.c | 2 + drivers/cpufreq/amd-pstate-trace.h | 96 +++ - drivers/cpufreq/amd-pstate.c | 812 ++++++++++++++++++ + drivers/cpufreq/amd-pstate.c | 724 ++++++++++++++++++ include/acpi/cppc_acpi.h | 5 + - tools/power/cpupower/lib/cpufreq.c | 44 +- - tools/power/cpupower/lib/cpufreq.h | 16 + - tools/power/cpupower/utils/cpufreq-info.c | 27 +- + tools/power/cpupower/lib/cpufreq.c | 21 +- + tools/power/cpupower/lib/cpufreq.h | 12 + + tools/power/cpupower/utils/cpufreq-info.c | 68 +- + tools/power/cpupower/utils/helpers/amd.c | 82 ++ tools/power/cpupower/utils/helpers/cpuid.c | 13 + - tools/power/cpupower/utils/helpers/helpers.h | 6 + - tools/power/cpupower/utils/helpers/misc.c | 27 + - 17 files changed, 1500 insertions(+), 4 deletions(-) + tools/power/cpupower/utils/helpers/helpers.h | 21 + + tools/power/cpupower/utils/helpers/misc.c | 64 ++ + 18 files changed, 1514 insertions(+), 58 deletions(-) create mode 100644 Documentation/admin-guide/pm/amd_pstate.rst create mode 100644 drivers/cpufreq/amd-pstate-trace.c create mode 100644 drivers/cpufreq/amd-pstate-trace.h @@ -740,14 +802,14 @@ index f40994c422dc..28db6156b55d 100644 intel_epb intel-speed-select diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h -index d0ce5cfd3ac1..f7aea50e3371 100644 +index d0ce5cfd3ac1..f23dc1abd485 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -313,6 +313,7 @@ #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ -+#define X86_FEATURE_AMD_CPPC_EXT (13*32+27) /* Collaborative Processor Performance Control Extension */ ++#define X86_FEATURE_AMD_CPPC (13*32+27) /* Collaborative Processor Performance Control */ /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ @@ -780,19 +842,29 @@ index a7c413432b33..ce42e15cf303 100644 #define MSR_F17H_IRPERF 0xc00000e9 diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c -index a4d4eebba1da..de4b30545215 100644 +index a4d4eebba1da..b285960c35e7 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c -@@ -1220,6 +1220,48 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) +@@ -411,7 +411,7 @@ bool acpi_cpc_valid(void) + struct cpc_desc *cpc_ptr; + int cpu; + +- for_each_possible_cpu(cpu) { ++ for_each_online_cpu(cpu) { + cpc_ptr = per_cpu(cpc_desc_ptr, cpu); + if (!cpc_ptr) + return false; +@@ -1220,6 +1220,54 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) } EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); +/** -+ * cppc_set_enable - Set to enable CPPC register. ++ * cppc_set_enable - Set to enable CPPC on the processor by writing the ++ * Continuous Performance Control package EnableRegister feild. + * @cpu: CPU for which to enable CPPC register. -+ * @enable: enable field to write into share memory. ++ * @enable: 0 - disable, 1 - enable CPPC feature on the processor. + * -+ * Return: 0 for success, -ERRNO otherwise. ++ * Return: 0 for success, -ERRNO or -EIO otherwise. + */ +int cppc_set_enable(int cpu, u32 enable) +{ @@ -802,6 +874,10 @@ index a4d4eebba1da..de4b30545215 100644 + struct cppc_pcc_data *pcc_ss_data = NULL; + int ret = -1; + ++ /* check the input value*/ ++ if (cpu < 0 || cpu > num_possible_cpus() - 1 || enable > 1) ++ return -ENODEV; ++ + if (!cpc_desc) { + pr_debug("No CPC descriptor for CPU:%d\n", cpu); + return -ENODEV; @@ -821,7 +897,8 @@ index a4d4eebba1da..de4b30545215 100644 + pcc_ss_data = pcc_data[pcc_ss_id]; + + down_write(&pcc_ss_data->pcc_lock); -+ send_pcc_cmd(pcc_ss_id, CMD_WRITE); ++ /* after writing CPC, transfer the ownership of PCC to platfrom */ ++ ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE); + up_write(&pcc_ss_data->pcc_lock); + } + @@ -857,7 +934,7 @@ index 92701a18bdd9..9cd7e338bdcd 100644 tristate "ACPI Processor P-States driver" depends on ACPI_PROCESSOR diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index 27d3bd7ea9d4..c1909475eaf9 100644 +index 27d3bd7ea9d4..04882bc4b145 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -17,6 +17,10 @@ obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o @@ -871,14 +948,14 @@ index 27d3bd7ea9d4..c1909475eaf9 100644 ################################################################################## # x86 drivers. # Link order matters. K8 is preferred to ACPI because of firmware bugs in early -@@ -24,6 +28,7 @@ obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o - # powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers. +@@ -25,6 +29,7 @@ obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o # speedstep-* is preferred over p4-clockmod. -+obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o ++obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o + obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o diff --git a/drivers/cpufreq/amd-pstate-trace.c b/drivers/cpufreq/amd-pstate-trace.c new file mode 100644 index 000000000000..891b696dcd69 @@ -991,10 +1068,10 @@ index 000000000000..50c85e150f30 +#include <trace/define_trace.h> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c new file mode 100644 -index 000000000000..9c60388d45ed +index 000000000000..b0353d13f74a --- /dev/null +++ b/drivers/cpufreq/amd-pstate.c -@@ -0,0 +1,812 @@ +@@ -0,0 +1,724 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * amd-pstate.c - AMD Processor P-state Frequency Driver @@ -1033,6 +1110,7 @@ index 000000000000..9c60388d45ed +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/uaccess.h> ++#include <linux/static_call.h> + +#include <acpi/processor.h> +#include <acpi/cppc_acpi.h> @@ -1049,8 +1127,7 @@ index 000000000000..9c60388d45ed +enum switch_type +{ + AMD_TARGET = 0, -+ AMD_ADJUST_PERF, -+ AMD_FAST_SWITCH, ++ AMD_ADJUST_PERF +}; + +static struct cpufreq_driver amd_pstate_driver; @@ -1076,14 +1153,6 @@ index 000000000000..9c60388d45ed + bool boost_supported; +}; + -+struct amd_pstate_perf_funcs { -+ int (*enable)(bool enable); -+ int (*init_perf)(struct amd_cpudata *cpudata); -+ void (*update_perf)(struct amd_cpudata *cpudata, -+ u32 min_perf, u32 des_perf, -+ u32 max_perf, bool fast_switch); -+}; -+ +static inline int pstate_enable(bool enable) +{ + return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable ? 1 : 0); @@ -1102,13 +1171,11 @@ index 000000000000..9c60388d45ed + return ret; +} + -+static int -+amd_pstate_enable(struct amd_pstate_perf_funcs *funcs, bool enable) -+{ -+ if (!funcs) -+ return -EINVAL; ++DEFINE_STATIC_CALL(amd_pstate_enable, pstate_enable); + -+ return funcs->enable(enable); ++static inline int amd_pstate_enable(bool enable) ++{ ++ return static_call(amd_pstate_enable)(enable); +} + +static int pstate_init_perf(struct amd_cpudata *cpudata) @@ -1120,9 +1187,10 @@ index 000000000000..9c60388d45ed + if (ret) + return ret; + -+ /* Some AMD processors has specific power features that the cppc entry -+ * doesn't indicate the highest performance. It will introduce the -+ * feature in following days. ++ /* ++ * TODO: Introduce AMD specific power feature. ++ * ++ * CPPC entry doesn't indicate the highest performance in some ASICs. + */ + WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); + @@ -1151,18 +1219,15 @@ index 000000000000..9c60388d45ed + return 0; +} + -+static int amd_pstate_init_perf(struct amd_cpudata *cpudata) -+{ -+ struct amd_pstate_perf_funcs *funcs = cpufreq_get_driver_data(); -+ -+ if (!funcs) -+ return -EINVAL; ++DEFINE_STATIC_CALL(amd_pstate_init_perf, pstate_init_perf); + -+ return funcs->init_perf(cpudata); ++static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata) ++{ ++ return static_call(amd_pstate_init_perf)(cpudata); +} + -+static void pstate_update_perf(struct amd_cpudata *cpudata, -+ u32 min_perf, u32 des_perf, u32 max_perf, ++static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, ++ u32 des_perf, u32 max_perf, + bool fast_switch) +{ + if (fast_switch) @@ -1185,28 +1250,23 @@ index 000000000000..9c60388d45ed + cppc_set_perf(cpudata->cpu, &perf_ctrls); +} + -+static int ++DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf); ++ ++static inline void +amd_pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, + u32 des_perf, u32 max_perf, bool fast_switch) +{ -+ struct amd_pstate_perf_funcs *funcs = cpufreq_get_driver_data(); -+ -+ if (!funcs) -+ return -EINVAL; -+ -+ funcs->update_perf(cpudata, min_perf, des_perf, -+ max_perf, fast_switch); -+ -+ return 0; ++ static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf, ++ max_perf, fast_switch); +} + -+static int ++static void +amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf, -+ u32 des_perf, u32 max_perf, bool fast_switch, -+ enum switch_type type) ++ u32 des_perf, u32 max_perf, bool fast_switch) +{ + u64 prev = READ_ONCE(cpudata->cppc_req_cached); + u64 value = prev; ++ enum switch_type type = fast_switch ? AMD_ADJUST_PERF : AMD_TARGET; + + value &= ~REQ_MIN_PERF(~0L); + value |= REQ_MIN_PERF(min_perf); @@ -1219,26 +1279,14 @@ index 000000000000..9c60388d45ed + + trace_amd_pstate_perf(min_perf, des_perf, max_perf, + cpudata->cpu, prev, value, type); ++ + if (value == prev) -+ return 0; ++ return; + + WRITE_ONCE(cpudata->cppc_req_cached, value); + -+ return amd_pstate_update_perf(cpudata, min_perf, des_perf, -+ max_perf, fast_switch); -+} -+ -+static bool amd_pstate_boost_supported(struct amd_cpudata *cpudata) -+{ -+ u32 highest_perf, nominal_perf; -+ -+ highest_perf = READ_ONCE(cpudata->highest_perf); -+ nominal_perf = READ_ONCE(cpudata->nominal_perf); -+ -+ if (highest_perf > nominal_perf) -+ return true; -+ -+ return false; ++ amd_pstate_update_perf(cpudata, min_perf, des_perf, ++ max_perf, fast_switch); +} + +static int amd_pstate_verify(struct cpufreq_policy_data *policy) @@ -1252,7 +1300,6 @@ index 000000000000..9c60388d45ed + unsigned int target_freq, + unsigned int relation) +{ -+ int ret; + struct cpufreq_freqs freqs; + struct amd_cpudata *cpudata = policy->driver_data; + unsigned long amd_max_perf, amd_min_perf, amd_des_perf, @@ -1272,11 +1319,11 @@ index 000000000000..9c60388d45ed + cpudata->max_freq); + + cpufreq_freq_transition_begin(policy, &freqs); -+ ret = amd_pstate_update(cpudata, amd_min_perf, amd_des_perf, -+ amd_max_perf, false, AMD_TARGET); ++ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf, ++ amd_max_perf, false); + cpufreq_freq_transition_end(policy, &freqs, false); + -+ return ret; ++ return 0; +} + +static void amd_pstate_adjust_perf(unsigned int cpu, @@ -1311,32 +1358,7 @@ index 000000000000..9c60388d45ed + amd_min_perf, amd_max_perf); + + amd_pstate_update(cpudata, amd_min_perf, amd_des_perf, -+ amd_max_perf, true, AMD_ADJUST_PERF); -+} -+ -+static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, -+ unsigned int target_freq) -+{ -+ u64 ratio; -+ struct amd_cpudata *cpudata = policy->driver_data; -+ unsigned long amd_max_perf, amd_min_perf, amd_des_perf, nominal_perf; -+ -+ if (!cpudata->max_freq) -+ return -ENODEV; -+ -+ amd_max_perf = READ_ONCE(cpudata->highest_perf); -+ amd_min_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); -+ -+ amd_des_perf = DIV_ROUND_UP(target_freq * amd_max_perf, -+ cpudata->max_freq); -+ -+ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf, -+ amd_max_perf, true, AMD_FAST_SWITCH); -+ -+ nominal_perf = READ_ONCE(cpudata->nominal_perf); -+ ratio = div_u64(amd_des_perf << SCHED_CAPACITY_SHIFT, nominal_perf); -+ -+ return cpudata->nominal_freq * ratio >> SCHED_CAPACITY_SHIFT; ++ amd_max_perf, true); +} + +static int amd_get_min_freq(struct amd_cpudata *cpudata) @@ -1441,6 +1463,14 @@ index 000000000000..9c60388d45ed + +static void amd_pstate_boost_init(struct amd_cpudata *cpudata) +{ ++ u32 highest_perf, nominal_perf; ++ ++ highest_perf = READ_ONCE(cpudata->highest_perf); ++ nominal_perf = READ_ONCE(cpudata->nominal_perf); ++ ++ if (highest_perf <= nominal_perf) ++ return; ++ + cpudata->boost_supported = true; + amd_pstate_driver.boost_enabled = true; +} @@ -1462,18 +1492,6 @@ index 000000000000..9c60388d45ed + return 0; +} + -+static struct amd_pstate_perf_funcs pstate_funcs = { -+ .enable = pstate_enable, -+ .init_perf = pstate_init_perf, -+ .update_perf = pstate_update_perf, -+}; -+ -+static struct amd_pstate_perf_funcs cppc_funcs = { -+ .enable = cppc_enable, -+ .init_perf = cppc_init_perf, -+ .update_perf = cppc_update_perf, -+}; -+ +static int amd_pstate_cpu_init(struct cpufreq_policy *policy) +{ + int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; @@ -1520,7 +1538,7 @@ index 000000000000..9c60388d45ed + /* It will be updated by governor */ + policy->cur = policy->cpuinfo.min_freq; + -+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT)) ++ if (boot_cpu_has(X86_FEATURE_AMD_CPPC)) + policy->fast_switch_possible = true; + + ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0], @@ -1547,8 +1565,7 @@ index 000000000000..9c60388d45ed + + policy->driver_data = cpudata; + -+ if (amd_pstate_boost_supported(cpudata)) -+ amd_pstate_boost_init(cpudata); ++ amd_pstate_boost_init(cpudata); + + return 0; + @@ -1579,7 +1596,7 @@ index 000000000000..9c60388d45ed +static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy, + char *buf) +{ -+ int ret = 0, max_freq; ++ int max_freq; + struct amd_cpudata *cpudata; + + cpudata = policy->driver_data; @@ -1588,15 +1605,13 @@ index 000000000000..9c60388d45ed + if (max_freq < 0) + return max_freq; + -+ ret += sprintf(&buf[ret], "%u\n", max_freq); -+ -+ return ret; ++ return sprintf(&buf[0], "%u\n", max_freq); +} + +static ssize_t show_amd_pstate_nominal_freq(struct cpufreq_policy *policy, + char *buf) +{ -+ int ret = 0, nominal_freq; ++ int nominal_freq; + struct amd_cpudata *cpudata; + + cpudata = policy->driver_data; @@ -1605,15 +1620,13 @@ index 000000000000..9c60388d45ed + if (nominal_freq < 0) + return nominal_freq; + -+ ret += sprintf(&buf[ret], "%u\n", nominal_freq); -+ -+ return ret; ++ return sprintf(&buf[0], "%u\n", nominal_freq); +} + +static ssize_t +show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *policy, char *buf) +{ -+ int ret = 0, freq; ++ int freq; + struct amd_cpudata *cpudata; + + cpudata = policy->driver_data; @@ -1622,82 +1635,65 @@ index 000000000000..9c60388d45ed + if (freq < 0) + return freq; + -+ ret += sprintf(&buf[ret], "%u\n", freq); -+ -+ return ret; ++ return sprintf(&buf[0], "%u\n", freq); +} + +static ssize_t show_amd_pstate_min_freq(struct cpufreq_policy *policy, char *buf) +{ -+ int ret = 0; -+ int freq; ++ int min_freq; + struct amd_cpudata *cpudata; + + cpudata = policy->driver_data; + -+ freq = amd_get_min_freq(cpudata); -+ if (freq < 0) -+ return freq; -+ -+ ret += sprintf(&buf[ret], "%u\n", freq); ++ min_freq = amd_get_min_freq(cpudata); ++ if (min_freq < 0) ++ return min_freq; + -+ return ret; ++ return sprintf(&buf[0], "%u\n", min_freq); +} + +static ssize_t +show_amd_pstate_highest_perf(struct cpufreq_policy *policy, char *buf) +{ -+ int ret = 0; + u32 perf; + struct amd_cpudata *cpudata = policy->driver_data; + + perf = READ_ONCE(cpudata->highest_perf); + -+ ret += sprintf(&buf[ret], "%u\n", perf); -+ -+ return ret; ++ return sprintf(&buf[0], "%u\n", perf); +} + +static ssize_t +show_amd_pstate_nominal_perf(struct cpufreq_policy *policy, char *buf) +{ -+ int ret = 0; + u32 perf; + struct amd_cpudata *cpudata = policy->driver_data; + + perf = READ_ONCE(cpudata->nominal_perf); + -+ ret += sprintf(&buf[ret], "%u\n", perf); -+ -+ return ret; ++ return sprintf(&buf[0], "%u\n", perf); +} + +static ssize_t +show_amd_pstate_lowest_nonlinear_perf(struct cpufreq_policy *policy, char *buf) +{ -+ int ret = 0; + u32 perf; + struct amd_cpudata *cpudata = policy->driver_data; + + perf = READ_ONCE(cpudata->lowest_nonlinear_perf); + -+ ret += sprintf(&buf[ret], "%u\n", perf); -+ -+ return ret; ++ return sprintf(&buf[0], "%u\n", perf); +} + +static ssize_t +show_amd_pstate_lowest_perf(struct cpufreq_policy *policy, char *buf) +{ -+ int ret = 0; + u32 perf; + struct amd_cpudata *cpudata = policy->driver_data; + + perf = READ_ONCE(cpudata->lowest_perf); + -+ ret += sprintf(&buf[ret], "%u\n", perf); -+ -+ return ret; ++ return sprintf(&buf[0], "%u\n", perf); +} + +static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy, @@ -1735,7 +1731,6 @@ index 000000000000..9c60388d45ed + .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, + .verify = amd_pstate_verify, + .target = amd_pstate_target, -+ .fast_switch = amd_pstate_fast_switch, + .init = amd_pstate_cpu_init, + .exit = amd_pstate_cpu_exit, + .set_boost = amd_pstate_set_boost, @@ -1746,7 +1741,6 @@ index 000000000000..9c60388d45ed +static int __init amd_pstate_init(void) +{ + int ret; -+ struct amd_pstate_perf_funcs *funcs; + + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + return -ENODEV; @@ -1762,25 +1756,24 @@ index 000000000000..9c60388d45ed + return -EEXIST; + + /* capability check */ -+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT)) { -+ pr_debug("%s, AMD CPPC extension functionality is supported\n", ++ if (boot_cpu_has(X86_FEATURE_AMD_CPPC)) { ++ pr_debug("%s, AMD CPPC MSR based functionality is supported\n", + __func__); -+ funcs = &pstate_funcs; + amd_pstate_driver.adjust_perf = amd_pstate_adjust_perf; + } else { -+ funcs = &cppc_funcs; ++ static_call_update(amd_pstate_enable, cppc_enable); ++ static_call_update(amd_pstate_init_perf, cppc_init_perf); ++ static_call_update(amd_pstate_update_perf, cppc_update_perf); + } + + /* enable amd pstate feature */ -+ ret = amd_pstate_enable(funcs, true); ++ ret = amd_pstate_enable(true); + if (ret) { + pr_err("%s, failed to enable amd-pstate with return %d\n", + __func__, ret); + return ret; + } + -+ amd_pstate_driver.driver_data = funcs; -+ + ret = cpufreq_register_driver(&amd_pstate_driver); + if (ret) { + pr_err("%s, return %d\n", __func__, ret); @@ -1792,13 +1785,9 @@ index 000000000000..9c60388d45ed + +static void __exit amd_pstate_exit(void) +{ -+ struct amd_pstate_perf_funcs *funcs; -+ -+ funcs = cpufreq_get_driver_data(); -+ + cpufreq_unregister_driver(&amd_pstate_driver); + -+ amd_pstate_enable(funcs, false); ++ amd_pstate_enable(false); +} + +module_init(amd_pstate_init); @@ -1831,103 +1820,124 @@ index 9f4985b4d64d..3fdae40a75fc 100644 { return -ENOTSUPP; diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c -index c3b56db8b921..1443080868da 100644 +index c3b56db8b921..02719cc400a1 100644 --- a/tools/power/cpupower/lib/cpufreq.c +++ b/tools/power/cpupower/lib/cpufreq.c -@@ -69,6 +69,14 @@ enum cpufreq_value { - SCALING_MIN_FREQ, - SCALING_MAX_FREQ, - STATS_NUM_TRANSITIONS, -+ AMD_PSTATE_HIGHEST_PERF, -+ AMD_PSTATE_NOMINAL_PERF, -+ AMD_PSTATE_LOWEST_NONLINEAR_PERF, -+ AMD_PSTATE_LOWEST_PERF, -+ AMD_PSTATE_MAX_FREQ, -+ AMD_PSTATE_NOMINAL_FREQ, -+ AMD_PSTATE_LOWEST_NONLINEAR_FREQ, -+ AMD_PSTATE_MIN_FREQ, - MAX_CPUFREQ_VALUE_READ_FILES +@@ -83,20 +83,21 @@ static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = { + [STATS_NUM_TRANSITIONS] = "stats/total_trans" }; -@@ -80,7 +88,15 @@ static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = { - [SCALING_CUR_FREQ] = "scaling_cur_freq", - [SCALING_MIN_FREQ] = "scaling_min_freq", - [SCALING_MAX_FREQ] = "scaling_max_freq", -- [STATS_NUM_TRANSITIONS] = "stats/total_trans" -+ [STATS_NUM_TRANSITIONS] = "stats/total_trans", -+ [AMD_PSTATE_HIGHEST_PERF] = "amd_pstate_highest_perf", -+ [AMD_PSTATE_NOMINAL_PERF] = "amd_pstate_nominal_perf", -+ [AMD_PSTATE_LOWEST_NONLINEAR_PERF] = "amd_pstate_lowest_nonlinear_perf", -+ [AMD_PSTATE_LOWEST_PERF] = "amd_pstate_lowest_perf", -+ [AMD_PSTATE_MAX_FREQ] = "amd_pstate_max_freq", -+ [AMD_PSTATE_NOMINAL_FREQ] = "amd_pstate_nominal_freq", -+ [AMD_PSTATE_LOWEST_NONLINEAR_FREQ] = "amd_pstate_lowest_nonlinear_freq", -+ [AMD_PSTATE_MIN_FREQ] = "amd_pstate_min_freq" - }; +- +-static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, +- enum cpufreq_value which) ++unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, ++ const char **table, ++ unsigned index, ++ unsigned size) + { + unsigned long value; + unsigned int len; + char linebuf[MAX_LINE_LEN]; + char *endp; +- if (which >= MAX_CPUFREQ_VALUE_READ_FILES) ++ if (!table && !table[index] && index >= size) + return 0; -@@ -774,3 +790,29 @@ unsigned long cpufreq_get_transitions(unsigned int cpu) - { - return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS); +- len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which], +- linebuf, sizeof(linebuf)); ++ len = sysfs_cpufreq_read_file(cpu, table[index], linebuf, ++ sizeof(linebuf)); + + if (len == 0) + return 0; +@@ -109,6 +110,14 @@ static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, + return value; } -+ -+int amd_pstate_boost_support(unsigned int cpu) -+{ -+ unsigned int highest_perf, nominal_perf; -+ -+ highest_perf = sysfs_cpufreq_get_one_value(cpu, AMD_PSTATE_HIGHEST_PERF); -+ nominal_perf = sysfs_cpufreq_get_one_value(cpu, AMD_PSTATE_NOMINAL_PERF); -+ -+ return highest_perf > nominal_perf ? 1 : 0; -+} -+ -+int amd_pstate_boost_enabled(unsigned int cpu) + ++static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, ++ enum cpufreq_value which) +{ -+ unsigned int cpuinfo_max, amd_pstate_max; -+ -+ cpuinfo_max = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MAX_FREQ); -+ amd_pstate_max = sysfs_cpufreq_get_one_value(cpu, AMD_PSTATE_MAX_FREQ); -+ -+ return cpuinfo_max == amd_pstate_max ? 1 : 0; ++ return cpufreq_get_sysfs_value_from_table(cpu, cpufreq_value_files, ++ which, ++ MAX_CPUFREQ_VALUE_READ_FILES); +} + -+unsigned amd_pstate_get_data(unsigned int cpu, enum amd_pstate_param param) -+{ -+ return sysfs_cpufreq_get_one_value(cpu, -+ param + AMD_PSTATE_HIGHEST_PERF); -+} + /* read access to files which contain one string */ + + enum cpufreq_string { diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h -index 95f4fd9e2656..954e72704fc0 100644 +index 95f4fd9e2656..107668c0c454 100644 --- a/tools/power/cpupower/lib/cpufreq.h +++ b/tools/power/cpupower/lib/cpufreq.h -@@ -203,6 +203,22 @@ int cpufreq_modify_policy_governor(unsigned int cpu, char *governor); +@@ -203,6 +203,18 @@ int cpufreq_modify_policy_governor(unsigned int cpu, char *governor); int cpufreq_set_frequency(unsigned int cpu, unsigned long target_frequency); -+int amd_pstate_boost_support(unsigned int cpu); -+int amd_pstate_boost_enabled(unsigned int cpu); -+ -+enum amd_pstate_param { -+ HIGHEST_PERF, -+ NOMINAL_PERF, -+ LOWEST_NONLINEAR_PERF, -+ LOWEST_PERF, -+ MAX_FREQ, -+ NOMINAL_FREQ, -+ LOWEST_NONLINEAR_FREQ, -+ MIN_FREQ, -+}; ++/* ++ * get the sysfs value from specific table ++ * ++ * Read the value with the sysfs file name from specific table. Does ++ * only work if the cpufreq driver has the specific sysfs interfaces. ++ */ + -+unsigned amd_pstate_get_data(unsigned int cpu, enum amd_pstate_param param); ++unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, ++ const char **table, ++ unsigned index, ++ unsigned size); + #ifdef __cplusplus } #endif diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c -index f9895e31ff5a..9eabed209adc 100644 +index f9895e31ff5a..f828f3c35a6f 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c -@@ -183,9 +183,30 @@ static int get_boost_mode_x86(unsigned int cpu) +@@ -84,43 +84,6 @@ static void proc_cpufreq_output(void) + } + + static int no_rounding; +-static void print_speed(unsigned long speed) +-{ +- unsigned long tmp; +- +- if (no_rounding) { +- if (speed > 1000000) +- printf("%u.%06u GHz", ((unsigned int) speed/1000000), +- ((unsigned int) speed%1000000)); +- else if (speed > 1000) +- printf("%u.%03u MHz", ((unsigned int) speed/1000), +- (unsigned int) (speed%1000)); +- else +- printf("%lu kHz", speed); +- } else { +- if (speed > 1000000) { +- tmp = speed%10000; +- if (tmp >= 5000) +- speed += 10000; +- printf("%u.%02u GHz", ((unsigned int) speed/1000000), +- ((unsigned int) (speed%1000000)/10000)); +- } else if (speed > 100000) { +- tmp = speed%1000; +- if (tmp >= 500) +- speed += 1000; +- printf("%u MHz", ((unsigned int) speed/1000)); +- } else if (speed > 1000) { +- tmp = speed%100; +- if (tmp >= 50) +- speed += 100; +- printf("%u.%01u MHz", ((unsigned int) speed/1000), +- ((unsigned int) (speed%1000)/100)); +- } +- } +- +- return; +-} +- + static void print_duration(unsigned long duration) + { + unsigned long tmp; +@@ -183,9 +146,12 @@ static int get_boost_mode_x86(unsigned int cpu) printf(_(" Supported: %s\n"), support ? _("yes") : _("no")); printf(_(" Active: %s\n"), active ? _("yes") : _("no")); @@ -1936,33 +1946,193 @@ index f9895e31ff5a..9eabed209adc 100644 - cpupower_cpu_info.vendor == X86_VENDOR_HYGON) { + if (cpupower_cpu_info.vendor == X86_VENDOR_AMD && + cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) { -+ printf(_(" AMD PSTATE Highest Performance: %u. Maximum Frequency: "), -+ amd_pstate_get_data(cpu, HIGHEST_PERF)); -+ print_speed(amd_pstate_get_data(cpu, MAX_FREQ)); -+ printf(".\n"); -+ -+ printf(_(" AMD PSTATE Nominal Performance: %u. Nominal Frequency: "), -+ amd_pstate_get_data(cpu, NOMINAL_PERF)); -+ print_speed(amd_pstate_get_data(cpu, NOMINAL_FREQ)); -+ printf(".\n"); -+ -+ printf(_(" AMD PSTATE Lowest Non-linear Performance: %u. Lowest Non-linear Frequency: "), -+ amd_pstate_get_data(cpu, LOWEST_NONLINEAR_PERF)); -+ print_speed(amd_pstate_get_data(cpu, LOWEST_NONLINEAR_FREQ)); -+ printf(".\n"); -+ -+ printf(_(" AMD PSTATE Lowest Performance: %u. Lowest Frequency: "), -+ amd_pstate_get_data(cpu, LOWEST_PERF)); -+ print_speed(amd_pstate_get_data(cpu, MIN_FREQ)); -+ printf(".\n"); ++ amd_pstate_show_perf_and_freq(cpu, no_rounding); + } else if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD && + cpupower_cpu_info.family >= 0x10) || + cpupower_cpu_info.vendor == X86_VENDOR_HYGON) { ret = decode_pstates(cpu, b_states, pstates, &pstate_no); if (ret) return ret; +@@ -254,11 +220,11 @@ static int get_boost_mode(unsigned int cpu) + if (freqs) { + printf(_(" boost frequency steps: ")); + while (freqs->next) { +- print_speed(freqs->frequency); ++ print_speed(freqs->frequency, no_rounding); + printf(", "); + freqs = freqs->next; + } +- print_speed(freqs->frequency); ++ print_speed(freqs->frequency, no_rounding); + printf("\n"); + cpufreq_put_available_frequencies(freqs); + } +@@ -277,7 +243,7 @@ static int get_freq_kernel(unsigned int cpu, unsigned int human) + return -EINVAL; + } + if (human) { +- print_speed(freq); ++ print_speed(freq, no_rounding); + } else + printf("%lu", freq); + printf(_(" (asserted by call to kernel)\n")); +@@ -296,7 +262,7 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human) + return -EINVAL; + } + if (human) { +- print_speed(freq); ++ print_speed(freq, no_rounding); + } else + printf("%lu", freq); + printf(_(" (asserted by call to hardware)\n")); +@@ -316,9 +282,9 @@ static int get_hardware_limits(unsigned int cpu, unsigned int human) + + if (human) { + printf(_(" hardware limits: ")); +- print_speed(min); ++ print_speed(min, no_rounding); + printf(" - "); +- print_speed(max); ++ print_speed(max, no_rounding); + printf("\n"); + } else { + printf("%lu %lu\n", min, max); +@@ -350,9 +316,9 @@ static int get_policy(unsigned int cpu) + return -EINVAL; + } + printf(_(" current policy: frequency should be within ")); +- print_speed(policy->min); ++ print_speed(policy->min, no_rounding); + printf(_(" and ")); +- print_speed(policy->max); ++ print_speed(policy->max, no_rounding); + + printf(".\n "); + printf(_("The governor \"%s\" may decide which speed to use\n" +@@ -436,7 +402,7 @@ static int get_freq_stats(unsigned int cpu, unsigned int human) + struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time); + while (stats) { + if (human) { +- print_speed(stats->frequency); ++ print_speed(stats->frequency, no_rounding); + printf(":%.2f%%", + (100.0 * stats->time_in_state) / total_time); + } else +@@ -486,11 +452,11 @@ static void debug_output_one(unsigned int cpu) + if (freqs) { + printf(_(" available frequency steps: ")); + while (freqs->next) { +- print_speed(freqs->frequency); ++ print_speed(freqs->frequency, no_rounding); + printf(", "); + freqs = freqs->next; + } +- print_speed(freqs->frequency); ++ print_speed(freqs->frequency, no_rounding); + printf("\n"); + cpufreq_put_available_frequencies(freqs); + } +diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c +index 97f2c857048e..d68d052ee4cb 100644 +--- a/tools/power/cpupower/utils/helpers/amd.c ++++ b/tools/power/cpupower/utils/helpers/amd.c +@@ -8,7 +8,9 @@ + #include <pci/pci.h> + + #include "helpers/helpers.h" ++#include "cpufreq.h" + ++/* ACPI P-States Helper Functions for AMD Processors ***************/ + #define MSR_AMD_PSTATE_STATUS 0xc0010063 + #define MSR_AMD_PSTATE 0xc0010064 + #define MSR_AMD_PSTATE_LIMIT 0xc0010061 +@@ -146,4 +148,84 @@ int amd_pci_get_num_boost_states(int *active, int *states) + pci_cleanup(pci_acc); + return 0; + } ++ ++/* ACPI P-States Helper Functions for AMD Processors ***************/ ++ ++/* AMD P-States Helper Functions ***************/ ++enum amd_pstate_value { ++ AMD_PSTATE_HIGHEST_PERF, ++ AMD_PSTATE_NOMINAL_PERF, ++ AMD_PSTATE_LOWEST_NONLINEAR_PERF, ++ AMD_PSTATE_LOWEST_PERF, ++ AMD_PSTATE_MAX_FREQ, ++ AMD_PSTATE_NOMINAL_FREQ, ++ AMD_PSTATE_LOWEST_NONLINEAR_FREQ, ++ AMD_PSTATE_MIN_FREQ, ++ MAX_AMD_PSTATE_VALUE_READ_FILES ++}; ++ ++static const char *amd_pstate_value_files[MAX_AMD_PSTATE_VALUE_READ_FILES] = { ++ [AMD_PSTATE_HIGHEST_PERF] = "amd_pstate_highest_perf", ++ [AMD_PSTATE_NOMINAL_PERF] = "amd_pstate_nominal_perf", ++ [AMD_PSTATE_LOWEST_NONLINEAR_PERF] = "amd_pstate_lowest_nonlinear_perf", ++ [AMD_PSTATE_LOWEST_PERF] = "amd_pstate_lowest_perf", ++ [AMD_PSTATE_MAX_FREQ] = "amd_pstate_max_freq", ++ [AMD_PSTATE_NOMINAL_FREQ] = "amd_pstate_nominal_freq", ++ [AMD_PSTATE_LOWEST_NONLINEAR_FREQ] = "amd_pstate_lowest_nonlinear_freq", ++ [AMD_PSTATE_MIN_FREQ] = "amd_pstate_min_freq" ++}; ++ ++static unsigned long amd_pstate_get_data(unsigned int cpu, ++ enum amd_pstate_value value) ++{ ++ return cpufreq_get_sysfs_value_from_table(cpu, ++ amd_pstate_value_files, ++ value, ++ MAX_AMD_PSTATE_VALUE_READ_FILES); ++} ++ ++void amd_pstate_boost_init(unsigned int cpu, int *support, int *active) ++{ ++ unsigned long highest_perf, nominal_perf, cpuinfo_min, ++ cpuinfo_max, amd_pstate_max; ++ ++ highest_perf = amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF); ++ nominal_perf = amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_PERF); ++ ++ *support = highest_perf > nominal_perf ? 1 : 0; ++ if (!(*support)) ++ return; ++ ++ cpufreq_get_hardware_limits(cpu, &cpuinfo_min, &cpuinfo_max); ++ amd_pstate_max = amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ); ++ ++ *active = cpuinfo_max == amd_pstate_max ? 1 : 0; ++} ++ ++void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding) ++{ ++ printf(_(" AMD PSTATE Highest Performance: %lu. Maximum Frequency: "), ++ amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF)); ++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ), no_rounding); ++ printf(".\n"); ++ ++ printf(_(" AMD PSTATE Nominal Performance: %lu. Nominal Frequency: "), ++ amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_PERF)); ++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_FREQ), ++ no_rounding); ++ printf(".\n"); ++ ++ printf(_(" AMD PSTATE Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "), ++ amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_NONLINEAR_PERF)); ++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_NONLINEAR_FREQ), ++ no_rounding); ++ printf(".\n"); ++ ++ printf(_(" AMD PSTATE Lowest Performance: %lu. Lowest Frequency: "), ++ amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_PERF)); ++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MIN_FREQ), no_rounding); ++ printf(".\n"); ++} ++ ++/* AMD P-States Helper Functions ***************/ + #endif /* defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c -index 72eb43593180..78218c54acca 100644 +index 72eb43593180..2a6dc104e76b 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -149,6 +149,19 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info) @@ -1970,7 +2140,7 @@ index 72eb43593180..78218c54acca 100644 cpuid_ebx(0x80000008) & (1 << 4)) cpu_info->caps |= CPUPOWER_CAP_AMD_RDPRU; + -+ if (cpupower_amd_pstate_enabled(0)) { ++ if (cpupower_amd_pstate_enabled()) { + cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE; + + /* @@ -1986,7 +2156,7 @@ index 72eb43593180..78218c54acca 100644 if (cpu_info->vendor == X86_VENDOR_INTEL) { diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h -index 33ffacee7fcb..eb43c14d1728 100644 +index 33ffacee7fcb..80755568afc4 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -73,6 +73,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, @@ -1997,48 +2167,64 @@ index 33ffacee7fcb..eb43c14d1728 100644 #define CPUPOWER_AMD_CPBDIS 0x02000000 -@@ -135,6 +136,11 @@ extern int decode_pstates(unsigned int cpu, int boost_states, +@@ -135,6 +136,16 @@ extern int decode_pstates(unsigned int cpu, int boost_states, extern int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, int * states); + -+/* AMD PSTATE enabling **************************/ ++/* AMD P-States stuff **************************/ ++extern unsigned long cpupower_amd_pstate_enabled(void); ++extern void amd_pstate_boost_init(unsigned int cpu, ++ int *support, int *active); ++extern void amd_pstate_show_perf_and_freq(unsigned int cpu, ++ int no_rounding); + -+extern unsigned long cpupower_amd_pstate_enabled(unsigned int cpu); ++/* AMD P-States stuff **************************/ + /* * CPUID functions returning a single datum */ -diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c -index fc6e34511721..aba979320760 100644 ---- a/tools/power/cpupower/utils/helpers/misc.c -+++ b/tools/power/cpupower/utils/helpers/misc.c -@@ -10,6 +10,7 @@ - #if defined(__i386__) || defined(__x86_64__) +@@ -167,6 +178,15 @@ static inline int cpufreq_has_boost_support(unsigned int cpu, int *support, + int *active, int * states) + { return -1; } - #include "cpupower_intern.h" -+#include "cpufreq.h" ++static inline unsigned long cpupower_amd_pstate_enabled(void) ++{ return 0; } ++static void amd_pstate_boost_init(unsigned int cpu, ++ int *support, int *active) ++{ return; } ++static inline void amd_pstate_show_perf_and_freq(unsigned int cpu, ++ int no_rounding) ++{ return; } ++ + /* cpuid and cpuinfo helpers **************************/ - #define MSR_AMD_HWCR 0xc0010015 + static inline unsigned int cpuid_eax(unsigned int op) { return 0; }; +@@ -184,5 +204,6 @@ extern struct bitmask *offline_cpus; + void get_cpustate(void); + void print_online_cpus(void); + void print_offline_cpus(void); ++void print_speed(unsigned long speed, int no_rounding); -@@ -39,6 +40,12 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, + #endif /* __CPUPOWERUTILS_HELPERS__ */ +diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c +index fc6e34511721..730f670ab90d 100644 +--- a/tools/power/cpupower/utils/helpers/misc.c ++++ b/tools/power/cpupower/utils/helpers/misc.c +@@ -39,6 +39,8 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, if (ret) return ret; } -+ } if ((cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) && -+ amd_pstate_boost_support(cpu)) { -+ *support = 1; -+ -+ if (amd_pstate_boost_enabled(cpu)) -+ *active = 1; ++ } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) { ++ amd_pstate_boost_init(cpu, support, active); } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA) *support = *active = 1; return 0; -@@ -83,6 +90,26 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val) +@@ -83,6 +85,26 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val) return 0; } -+unsigned long cpupower_amd_pstate_enabled(unsigned int cpu) ++unsigned long cpupower_amd_pstate_enabled(void) +{ + char linebuf[MAX_LINE_LEN]; + char path[SYSFS_PATH_MAX]; @@ -2046,7 +2232,7 @@ index fc6e34511721..aba979320760 100644 + char *endp; + + snprintf(path, sizeof(path), -+ PATH_TO_CPU "cpu%u/cpufreq/is_amd_pstate_enabled", cpu); ++ PATH_TO_CPU "cpu0/cpufreq/is_amd_pstate_enabled"); + + if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) + return 0; @@ -2061,6 +2247,52 @@ index fc6e34511721..aba979320760 100644 #endif /* #if defined(__i386__) || defined(__x86_64__) */ /* get_cpustate +@@ -144,3 +166,45 @@ void print_offline_cpus(void) + printf(_("cpupower set operation was not performed on them\n")); + } + } ++ ++/* ++ * print_speed ++ * ++ * Print the exact CPU frequency with appropriate unit ++ */ ++void print_speed(unsigned long speed, int no_rounding) ++{ ++ unsigned long tmp; ++ ++ if (no_rounding) { ++ if (speed > 1000000) ++ printf("%u.%06u GHz", ((unsigned int) speed/1000000), ++ ((unsigned int) speed%1000000)); ++ else if (speed > 1000) ++ printf("%u.%03u MHz", ((unsigned int) speed/1000), ++ (unsigned int) (speed%1000)); ++ else ++ printf("%lu kHz", speed); ++ } else { ++ if (speed > 1000000) { ++ tmp = speed%10000; ++ if (tmp >= 5000) ++ speed += 10000; ++ printf("%u.%02u GHz", ((unsigned int) speed/1000000), ++ ((unsigned int) (speed%1000000)/10000)); ++ } else if (speed > 100000) { ++ tmp = speed%1000; ++ if (tmp >= 500) ++ speed += 1000; ++ printf("%u MHz", ((unsigned int) speed/1000)); ++ } else if (speed > 1000) { ++ tmp = speed%100; ++ if (tmp >= 50) ++ speed += 100; ++ printf("%u.%01u MHz", ((unsigned int) speed/1000), ++ ((unsigned int) (speed%1000)/100)); ++ } ++ } ++ ++ return; ++} -- 2.33.0 |