summarylogtreecommitdiffstats
path: root/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch
diff options
context:
space:
mode:
authordragonn2021-10-02 18:39:30 +0200
committerdragonn2021-10-02 18:46:42 +0200
commit1a7d00bb70c5f03cf9ec04e6ab94ad47aa7be450 (patch)
treeb4a3f38d9177d6b3a7fb3ef91ad184a72c01a16c /sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch
parent3fd8f33c94d648c87abfb4db970367cf6b6633a6 (diff)
downloadaur-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.patch892
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