summarylogtreecommitdiffstats
path: root/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch
diff options
context:
space:
mode:
authordragonn2021-09-18 10:01:44 +0200
committerdragonn2021-09-18 10:01:44 +0200
commit825d71ed713c470164cb24131dd6af6fcb19664e (patch)
tree2422ae50eb0bf5fec3e80d533425293bf1a57730 /sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch
parent8f5e12722e0aa4ead0854037a38ff6dbb1981a6b (diff)
downloadaur-825d71ed713c470164cb24131dd6af6fcb19664e.tar.gz
5.14.5
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.patch2880
1 files changed, 1246 insertions, 1634 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 d313ef86c88f..09471946e6f9 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,16 +1,744 @@
-From 674082f34ac8bfab164a630a275eac291e1bd7be Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Thu, 28 Jan 2021 10:50:26 +0800
-Subject: [PATCH 01/19] x86/cpufreatures: add AMD CPPC extension feature flag
+From 1cf7e7f39c0c1a259ffd8c58b69edfc933936913 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
-Add Collaborative Processor Performance Control Extension feature flag
-for AMD processors.
+Squashed commit of the following:
-Signed-off-by: Huang Rui <ray.huang@amd.com>
+commit aee7d6c2aa9fde5120b03083676ad86bf293aeaa
+Author: Huang Rui <ray.huang@amd.com>
+Date: Thu Jun 10 23:40:18 2021 +0800
+
+ Documentation: amd-pstate: add amd-pstate driver introduction
+
+ Introduce the amd-pstate driver design and implementation.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit d5130811e36f5557e2678de2f612c2db00a5c719
+Author: Huang Rui <ray.huang@amd.com>
+Date: Thu Jun 10 23:48:03 2021 +0800
+
+ cpupower: print amd-pstate information on cpupower
+
+ amd-pstate kernel module is using the fine grain frequency instead of
+ acpi hardware pstate. So the performance and frequency values should be
+ printed in frequency-info.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 8c239cb8a6e3704a75ab4139fd275a7e17b336c6
+Author: Huang Rui <ray.huang@amd.com>
+Date: Sun Jun 20 18:25:55 2021 +0800
+
+ cpupower: add amd-pstate get data function to query the info
+
+ Frequency-info needs an interface to query the current amd-pstate data.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit ce0b684f184fee1fba6b6e0ef4ae4506a0d275c1
+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.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 97f78342eb9bcecfe44ef5307941dea1051e3a75
+Author: Huang Rui <ray.huang@amd.com>
+Date: Sun Jun 20 17:07:25 2021 +0800
+
+ cpupower: add amd-pstate sysfs entries into libcpufreq
+
+ These amd-pstate sysfs entries will be used on cpupower for amd-pstate
+ kernel module.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit d99ecc31f798a4025baaea72607246dadedefca0
+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.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit f766224ca2c54192b9e9abaa50ce58ef5e72670d
+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.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 0eca00885d7ce1cf7c03b8999fce887c9bafc411
+Author: Huang Rui <ray.huang@amd.com>
+Date: Mon Jun 14 22:52:01 2021 +0800
+
+ cpupower: add AMD P-state capability flag
+
+ Add AMD P-state capability flag in cpupower to indicate AMD new P-state
+ kernel module support on Ryzen processors.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 9a70d7b125cad2356910cbf04e476d53b458c786
+Author: Huang Rui <ray.huang@amd.com>
+Date: Sun Jun 20 15:01:08 2021 +0800
+
+ cpufreq: amd: add amd-pstate performance attributes
+
+ Introduce sysfs attributes to get the different level amd-pstate
+ performances.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 48c5ae9172d62b6a6a8220f27afeaf47408ebb66
+Author: Huang Rui <ray.huang@amd.com>
+Date: Sun Jun 20 13:26:01 2021 +0800
+
+ cpufreq: amd: add amd-pstate frequencies attributes
+
+ Introduce sysfs attributes to get the different level processor
+ frequencies.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 4d003338827eca88097f35fae6e3ec75566bc788
+Author: Huang Rui <ray.huang@amd.com>
+Date: Sat Jun 19 23:41:30 2021 +0800
+
+ cpufreq: amd: add amd-pstate checking support check attribute
+
+ The amd-pstate hardware support check will be needed by cpupower to know
+ whether amd-pstate is enabled and supported.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit e8aa42d8143a5c8b65a63de34cd38bdc6d70fd82
+Author: Huang Rui <ray.huang@amd.com>
+Date: Thu Jun 10 23:13:00 2021 +0800
+
+ cpufreq: amd: add boost mode support for amd-pstate
+
+ If the sbios supports the boost mode of amd-pstate, let's switch to
+ boost enabled by default.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 1cb45daf02f2cad44457ccc237c9d74f60eec621
+Author: Huang Rui <ray.huang@amd.com>
+Date: Thu Jun 10 20:24:00 2021 +0800
+
+ cpufreq: amd: add trace for amd-pstate module
+
+ Add trace event to monitor the performance value changes which is
+ controlled by cpu governors.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 152251e4cc636f4748d308ac31089ae7fd4e09c9
+Author: Huang Rui <ray.huang@amd.com>
+Date: Mon Aug 9 19:06:51 2021 +0800
+
+ cpufreq: amd: add acpi cppc function as the backend for legacy processors
+
+ In some old Zen based processors, they are using the shared memory that
+ exposed from ACPI SBIOS.
+
+ Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit a2a9f14e19c4b34986e6410dd4f430449a32d2a3
+Author: Huang Rui <ray.huang@amd.com>
+Date: Fri Aug 13 18:43:47 2021 +0800
+
+ cpufreq: amd: add fast switch function for amd-pstate module
+
+ Introduce the fast switch function for amd-pstate module on the AMD
+ processors which support the full MSR register control. It's able to
+ decrease the lattency on interrupt context.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit ffb5347387a6a070554d2e6f6af918ffbf1965c4
+Author: Huang Rui <ray.huang@amd.com>
+Date: Thu Jun 10 18:04:45 2021 +0800
+
+ cpufreq: amd: introduce a new amd pstate driver to support future processors
+
+ amd-pstate is the AMD CPU performance scaling driver that introduces a
+ new CPU frequency control mechanism on AMD Zen based CPU series in Linux
+ kernel. The new mechanism is based on Collaborative processor
+ performance control (CPPC) which is finer grain frequency management
+ than legacy ACPI hardware P-States. Current AMD CPU platforms are using
+ the ACPI P-states driver to manage CPU frequency and clocks with
+ switching only in 3 P-states. AMD P-States is to replace the ACPI
+ P-states controls, allows a flexible, low-latency interface for the
+ Linux kernel to directly communicate the performance hints to hardware.
+
+ "amd-pstate" leverages the Linux kernel governors such as *schedutil*,
+ *ondemand*, etc. to manage the performance hints which are provided by CPPC
+ hardware functionality. The first version for amd-pstate is to support one
+ of the Zen3 processors, and we will support more in future after we verify
+ the hardware and SBIOS functionalities.
+
+ There are two types of hardware implementations for amd-pstate: one is full
+ MSR support and another is shared memory support. It can use
+ X86_FEATURE_AMD_CPPC_EXT feature flag to distinguish the different types.
+
+ Using the new AMD P-States method + kernel governors (*schedutil*,
+ *ondemand*, ...) to manage the frequency update is the most appropriate
+ bridge between AMD Zen based hardware processor and Linux kernel, the
+ processor is able to ajust to the most efficiency frequency according to
+ the kernel scheduler loading.
+
+ Performance Per Watt (PPW) Caculation:
+
+ The PPW caculation is referred by below paper:
+ https://software.intel.com/content/dam/develop/external/us/en/documents/performance-per-what-paper.pdf
+
+ Below formula is referred from below spec to measure the PPW:
+
+ (F / t) / P = F * t / (t * E) = F / E,
+
+ "F" is the number of frames per second.
+ "P" is power measurd in watts.
+ "E" is energy measured in joules.
+
+ We use the RAPL interface with "perf" tool to get the energy data of the
+ package power.
+
+ The data comparsions between amd-pstate and acpi-freq module are tested on
+ AMD Cezanne processor:
+
+ 1) TBench CPU benchmark:
+
+ +---------------------------------------------------------------------+
+ | |
+ | TBench (Performance Per Watt) |
+ | Higher is better |
+ +-------------------+------------------------+------------------------+
+ | | Performance Per Watt | Performance Per Watt |
+ | Kernel Module | (Schedutil) | (Ondemand) |
+ | | Unit: MB / (s * J) | Unit: MB / (s * J) |
+ +-------------------+------------------------+------------------------+
+ | | | |
+ | acpi-cpufreq | 3.022 | 2.969 |
+ | | | |
+ +-------------------+------------------------+------------------------+
+ | | | |
+ | amd-pstate | 3.131 | 3.284 |
+ | | | |
+ +-------------------+------------------------+------------------------+
+
+ 2) Gitsource CPU benchmark:
+
+ +---------------------------------------------------------------------+
+ | |
+ | Gitsource (Performance Per Watt) |
+ | Higher is better |
+ +-------------------+------------------------+------------------------+
+ | | Performance Per Watt | Performance Per Watt |
+ | Kernel Module | (Schedutil) | (Ondemand) |
+ | | Unit: 1 / (s * J) | Unit: 1 / (s * J) |
+ +-------------------+------------------------+------------------------+
+ | | | |
+ | acpi-cpufreq | 3.42172E-07 | 2.74508E-07 |
+ | | | |
+ +-------------------+------------------------+------------------------+
+ | | | |
+ | amd-pstate | 4.09141E-07 | 3.47610E-07 |
+ | | | |
+ +-------------------+------------------------+------------------------+
+
+ 3) Speedometer 2.0 CPU benchmark:
+
+ +---------------------------------------------------------------------+
+ | |
+ | Speedometer 2.0 (Performance Per Watt) |
+ | Higher is better |
+ +-------------------+------------------------+------------------------+
+ | | Performance Per Watt | Performance Per Watt |
+ | Kernel Module | (Schedutil) | (Ondemand) |
+ | | Unit: 1 / (s * J) | Unit: 1 / (s * J) |
+ +-------------------+------------------------+------------------------+
+ | | | |
+ | acpi-cpufreq | 0.116111767 | 0.110321664 |
+ | | | |
+ +-------------------+------------------------+------------------------+
+ | | | |
+ | amd-pstate | 0.115825281 | 0.122024299 |
+ | | | |
+ +-------------------+------------------------+------------------------+
+
+ According to above average data, we can see this solution has shown better
+ performance per watt scaling on mobile CPU benchmarks in most of cases.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 5648469cb7cd30bc5bbd460b362c09223bdec3e5
+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.
+
+ Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit a0f215fdf3e24f2a74aa767cb5faef008ca3881e
+Author: Huang Rui <ray.huang@amd.com>
+Date: Mon Jan 25 15:50:24 2021 +0800
+
+ x86/msr: add AMD CPPC MSR definitions
+
+ AMD CPPC (Collaborative Processor Performance Control) function uses MSR
+ registers to manage the performance hints. So add the MSR register macro
+ here.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 1bff64e92f53c19784369a0cc1b7a05c918ed941
+Author: Huang Rui <ray.huang@amd.com>
+Date: Thu Jan 28 10:50:26 2021 +0800
+
+ x86/cpufreatures: add AMD CPPC extension feature flag
+
+ Add Collaborative Processor Performance Control Extension feature flag
+ for AMD processors.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
---
- arch/x86/include/asm/cpufeatures.h | 1 +
- 1 file changed, 1 insertion(+)
+ 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/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 ++++++++++++++++++
+ 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/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(-)
+ 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
+ create mode 100644 drivers/cpufreq/amd-pstate.c
+diff --git a/Documentation/admin-guide/pm/amd_pstate.rst b/Documentation/admin-guide/pm/amd_pstate.rst
+new file mode 100644
+index 000000000000..c3659dde0cee
+--- /dev/null
++++ b/Documentation/admin-guide/pm/amd_pstate.rst
+@@ -0,0 +1,377 @@
++.. SPDX-License-Identifier: GPL-2.0
++.. include:: <isonum.txt>
++
++===============================================
++``amd-pstate`` CPU Performance Scaling Driver
++===============================================
++
++:Copyright: |copy| 2021 Advanced Micro Devices, Inc.
++
++:Author: Huang Rui <ray.huang@amd.com>
++
++
++Introduction
++===================
++
++``amd-pstate`` is the AMD CPU performance scaling driver that introduces a
++new CPU frequency control mechanism on modern AMD APU and CPU series in
++Linux kernel. The new mechanism is based on Collaborative Processor
++Performance Control (CPPC) which provides finer grain frequency management
++than legacy ACPI hardware P-States. Current AMD CPU/APU platforms are using
++the ACPI P-states driver to manage CPU frequency and clocks with switching
++only in 3 P-states. CPPC replaces the ACPI P-states controls, allows a
++flexible, low-latency interface for the Linux kernel to directly
++communicate the performance hints to hardware.
++
++``amd-pstate`` leverages the Linux kernel governors such as ``schedutil``,
++``ondemand``, etc. to manage the performance hints which are provided by
++CPPC hardware functionality that internally follows the hardware
++specification (for details refer to AMD64 Architecture Programmer's Manual
++Volume 2: System Programming [1]_). Currently ``amd-pstate`` supports basic
++frequency control function according to kernel governors on some of the
++Zen2 and Zen3 processors, and we will implement more AMD specific functions
++in future after we verify them on the hardware and SBIOS.
++
++
++AMD CPPC Overview
++=======================
++
++Collaborative Processor Performance Control (CPPC) interface enumerates a
++continuous, abstract, and unit-less performance value in a scale that is
++not tied to a specific performance state / frequency. This is an ACPI
++standard [2]_ which software can specify application performance goals and
++hints as a relative target to the infrastructure limits. AMD processors
++provides the low latency register model (MSR) instead of AML code
++interpreter for performance adjustments. ``amd-pstate`` will initialize a
++``struct cpufreq_driver`` instance ``amd_pstate_driver`` with the callbacks
++to manage each performance update behavior. ::
++
++ Highest Perf ------>+-----------------------+ +-----------------------+
++ | | | |
++ | | | |
++ | | Max Perf ---->| |
++ | | | |
++ | | | |
++ Nominal Perf ------>+-----------------------+ +-----------------------+
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | Desired Perf ---->| |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ | | | |
++ Lowest non- | | | |
++ linear perf ------>+-----------------------+ +-----------------------+
++ | | | |
++ | | Lowest perf ---->| |
++ | | | |
++ Lowest perf ------>+-----------------------+ +-----------------------+
++ | | | |
++ | | | |
++ | | | |
++ 0 ------>+-----------------------+ +-----------------------+
++
++ AMD P-States Performance Scale
++
++
++.. _perf_cap:
++
++AMD CPPC Performance Capability
++--------------------------------
++
++Highest Performance (RO)
++.........................
++
++It is the absolute maximum performance an individual processor may reach,
++assuming ideal conditions. This performance level may not be sustainable
++for long durations and may only be achievable if other platform components
++are in a specific state; for example, it may require other processors be in
++an idle state. This would be equivalent to the highest frequencies
++supported by the processor.
++
++Nominal (Guaranteed) Performance (RO)
++......................................
++
++It is the maximum sustained performance level of the processor, assuming
++ideal operating conditions. In absence of an external constraint (power,
++thermal, etc.) this is the performance level the processor is expected to
++be able to maintain continuously. All cores/processors are expected to be
++able to sustain their nominal performance state simultaneously.
++
++Lowest non-linear Performance (RO)
++...................................
++
++It is the lowest performance level at which nonlinear power savings are
++achieved, for example, due to the combined effects of voltage and frequency
++scaling. Above this threshold, lower performance levels should be generally
++more energy efficient than higher performance levels. This register
++effectively conveys the most efficient performance level to ``amd-pstate``.
++
++Lowest Performance (RO)
++........................
++
++It is the absolute lowest performance level of the processor. Selecting a
++performance level lower than the lowest nonlinear performance level may
++cause an efficiency penalty but should reduce the instantaneous power
++consumption of the processor.
++
++AMD CPPC Performance Control
++------------------------------
++
++``amd-pstate`` passes performance goals through these registers. The
++register drives the behavior of the desired performance target.
++
++Minimum requested performance (RW)
++...................................
++
++``amd-pstate`` specifies the minimum allowed performance level.
++
++Maximum requested performance (RW)
++...................................
++
++``amd-pstate`` specifies a limit the maximum performance that is expected
++to be supplied by the hardware.
++
++Desired performance target (RW)
++...................................
++
++``amd-pstate`` specifies a desired target in the CPPC performance scale as
++a relative number. This can be expressed as percentage of nominal
++performance (infrastructure max). Below the nominal sustained performance
++level, desired performance expresses the average performance level of the
++processor subject to hardware. Above the nominal performance level,
++processor must provide at least nominal performance requested and go higher
++if current operating conditions allow.
++
++Energy Performance Preference (EPP) (RW)
++.........................................
++
++Provides a hint to the hardware if software wants to bias toward performance
++(0x0) or energy efficiency (0xff).
++
++
++Key Governors Support
++=======================
++
++``amd-pstate`` can be used with all the (generic) scaling governors listed
++by the ``scaling_available_governors`` policy attribute in ``sysfs``. Then,
++it is responsible for the configuration of policy objects corresponding to
++CPUs and provides the ``CPUFreq`` core (and the scaling governors attached
++to the policy objects) with accurate information on the maximum and minimum
++operating frequencies supported by the hardware. Users can check the
++``scaling_cur_freq`` information comes from the ``CPUFreq`` core.
++
++``amd-pstate`` mainly supports ``schedutil`` and ``ondemand`` for dynamic
++frequency control. It is to fine tune the processor configuration on
++``amd-pstate`` to the ``schedutil`` with CPU CFS scheduler. ``amd-pstate``
++registers adjust_perf callback to implement the CPPC similar performance
++update behavior. It is initialized by ``sugov_start`` and then populate the
++CPU's update_util_data pointer to assign ``sugov_update_single_perf`` as
++the utilization update callback function in CPU scheduler. CPU scheduler
++will call ``cpufreq_update_util`` and assign the target performance
++according to the ``struct sugov_cpu`` that utilization update belongs to.
++Then ``amd-pstate`` updates the desired performance according to the CPU
++scheduler assigned.
++
++
++Processor Support
++=======================
++
++The ``amd-pstate`` initialization will fail if the _CPC in ACPI SBIOS is
++not existed at the detected processor, and it uses ``acpi_cpc_valid`` to
++check the _CPC existence. All Zen based processors support legacy ACPI
++hardware P-States function, so while the ``amd-pstate`` fails to be
++initialized, the kernel will fall back to initialize ``acpi-cpufreq``
++driver.
++
++There are two types of hardware implementations for ``amd-pstate``: one is
++`Full MSR Support <perf_cap_>`_ and another is `Shared Memory Support
++<perf_cap_>`_. It can use :c:macro:`X86_FEATURE_AMD_CPPC_EXT` feature flag
++(for details refer to Processor Programming Reference (PPR) for AMD Family
++19h Model 21h, Revision B0 Processors [3]_) to indicate the different
++types. ``amd-pstate`` is to register different ``amd_pstate_perf_funcs``
++instances for different hardware implementations.
++
++Currently, some of Zen2 and Zen3 processors support ``amd-pstate``. In the
++future, it will be supported on more and more AMD processors.
++
++Full MSR Support
++-----------------
++
++Some new Zen3 processors such as Cezanne provide the MSR registers directly
++while the :c:macro:`X86_FEATURE_AMD_CPPC_EXT` CPU feature flag is set.
++``amd-pstate`` can handle the MSR register to implement the fast switch
++function in ``CPUFreq`` that can shrink latency of frequency control on the
++interrupt context.
++
++Shared Memory Support
++----------------------
++
++If :c:macro:`X86_FEATURE_AMD_CPPC_EXT` CPU feature flag is not set, that
++means the processor supports shared memory solution. In this case,
++``amd-pstate`` uses the ``cppc_acpi`` helper methods to implement the
++callback functions of ``amd_pstate_perf_funcs``.
++
++
++AMD P-States and ACPI hardware P-States always can be supported in one
++processor. But AMD P-States has the higher priority and if it is enabled
++with :c:macro:`MSR_AMD_CPPC_ENABLE` or ``cppc_set_enable``, it will respond
++to the request from AMD P-States.
++
++
++User Space Interface in ``sysfs``
++==================================
++
++``amd-pstate`` exposes several global attributes (files) in ``sysfs`` to
++control its functionality at the system level. They located in the
++``/sys/devices/system/cpu/cpufreq/policyX/`` directory and affect all CPUs. ::
++
++ root@hr-test1:/home/ray# ls /sys/devices/system/cpu/cpufreq/policy0/*amd*
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_highest_perf
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_freq
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_perf
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_perf
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_max_freq
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_min_freq
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_nominal_freq
++ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_nominal_perf
++ /sys/devices/system/cpu/cpufreq/policy0/is_amd_pstate_enabled
++
++
++``is_amd_pstate_enabled``
++
++Query whether current kernel loads ``amd-pstate`` to enable the AMD
++P-States functionality.
++This attribute is read-only.
++
++``amd_pstate_highest_perf / amd_pstate_max_freq``
++
++Maximum CPPC performance and CPU frequency that the driver is allowed to
++set in percent of the maximum supported CPPC performance level (the highest
++performance supported in `AMD CPPC Performance Capability <perf_cap_>`_).
++This attribute is read-only.
++
++``amd_pstate_nominal_perf / amd_pstate_nominal_freq``
++
++Nominal CPPC performance and CPU frequency that the driver is allowed to
++set in percent of the maximum supported CPPC performance level (Please see
++nominal performance in `AMD CPPC Performance Capability <perf_cap_>`_).
++This attribute is read-only.
++
++``amd_pstate_lowest_nonlinear_perf / amd_pstate_lowest_nonlinear_freq``
++
++The lowest non-linear CPPC performance and CPU frequency that the driver is
++allowed to set in percent of the maximum supported CPPC performance level
++(Please see the lowest non-linear performance in `AMD CPPC Performance
++Capability <perf_cap_>`_).
++This attribute is read-only.
++
++``amd_pstate_lowest_perf / amd_pstate_min_freq``
++
++The lowest physical CPPC performance and CPU frequency.
++This attribute is read-only.
++
++
++``amd-pstate`` vs ``acpi-cpufreq``
++======================================
++
++On majority of AMD platforms supported by ``acpi-cpufreq``, the ACPI tables
++provided by the platform firmware used for CPU performance scaling, but
++only provides 3 P-states on AMD processors.
++However, on modern AMD APU and CPU series, it provides the collaborative
++processor performance control according to ACPI protocol and customize this
++for AMD platforms. That is fine-grain and continuous frequency range
++instead of the legacy hardware P-states. ``amd-pstate`` is the kernel
++module which supports the new AMD P-States mechanism on most of future AMD
++platforms. The AMD P-States mechanism will be the more performance and energy
++efficiency frequency management method on AMD processors.
++
++``cpupower`` tool support for ``amd-pstate``
++===============================================
++
++``amd-pstate`` is supported on ``cpupower`` tool that can be used to dump the frequency
++information. And it is in progress to support more and more operations for new
++``amd-pstate`` module with this tool. ::
++
++ root@hr-test1:/home/ray# cpupower frequency-info
++ analyzing CPU 0:
++ driver: amd-pstate
++ CPUs which run at the same hardware frequency: 0
++ CPUs which need to have their frequency coordinated by software: 0
++ maximum transition latency: 131 us
++ hardware limits: 400 MHz - 4.68 GHz
++ available cpufreq governors: ondemand conservative powersave userspace performance schedutil
++ current policy: frequency should be within 400 MHz and 4.68 GHz.
++ The governor "schedutil" may decide which speed to use
++ within this range.
++ current CPU frequency: Unable to call hardware
++ current CPU frequency: 4.02 GHz (asserted by call to kernel)
++ boost state support:
++ Supported: yes
++ Active: yes
++ AMD PSTATE Highest Performance: 166. Maximum Frequency: 4.68 GHz.
++ AMD PSTATE Nominal Performance: 117. Nominal Frequency: 3.30 GHz.
++ AMD PSTATE Lowest Non-linear Performance: 39. Lowest Non-linear Frequency: 1.10 GHz.
++ AMD PSTATE Lowest Performance: 15. Lowest Frequency: 400 MHz.
++
++
++Diagnostics and Tuning
++=======================
++
++Trace Events
++--------------
++
++There are two static trace events that can be used for ``amd-pstate``
++diagnostics. One of them is the cpu_frequency trace event generally used
++by ``CPUFreq``, and the other one is the ``amd_pstate_perf`` trace event
++specific to ``amd-pstate``. The following sequence of shell commands can
++be used to enable them and see their output (if the kernel is generally
++configured to support event tracing). ::
++
++ root@hr-test1:/home/ray# cd /sys/kernel/tracing/
++ root@hr-test1:/sys/kernel/tracing# echo 1 > events/amd_cpu/enable
++ root@hr-test1:/sys/kernel/tracing# cat trace
++ # tracer: nop
++ #
++ # entries-in-buffer/entries-written: 47827/42233061 #P:2
++ #
++ # _-----=> irqs-off
++ # / _----=> need-resched
++ # | / _---=> hardirq/softirq
++ # || / _--=> preempt-depth
++ # ||| / delay
++ # TASK-PID CPU# |||| TIMESTAMP FUNCTION
++ # | | | |||| | |
++ <idle>-0 [000] d.s. 244057.464842: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
++ <idle>-0 [000] d.h. 244057.475436: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
++ <idle>-0 [000] d.h. 244057.476629: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
++ <idle>-0 [000] d.s. 244057.484847: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
++ <idle>-0 [000] d.h. 244057.499821: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
++ avahi-daemon-528 [000] d... 244057.513568: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
++
++The cpu_frequency trace event will be triggered either by the ``schedutil`` scaling
++governor (for the policies it is attached to), or by the ``CPUFreq`` core (for the
++policies with other scaling governors).
++
++
++Reference
++===========
++
++.. [1] AMD64 Architecture Programmer's Manual Volume 2: System Programming,
++ https://www.amd.com/system/files/TechDocs/24593.pdf
++
++.. [2] Advanced Configuration and Power Interface Specification,
++ https://uefi.org/sites/default/files/resources/ACPI_Spec_6_4_Jan22.pdf
++
++.. [3] Processor Programming Reference (PPR) for AMD Family 19h Model 21h, Revision B0 Processors
++ https://www.amd.com/system/files/TechDocs/55898_B1_pub_0.50.zip
++
+diff --git a/Documentation/admin-guide/pm/working-state.rst b/Documentation/admin-guide/pm/working-state.rst
+index f40994c422dc..28db6156b55d 100644
+--- a/Documentation/admin-guide/pm/working-state.rst
++++ b/Documentation/admin-guide/pm/working-state.rst
+@@ -11,6 +11,7 @@ Working-State Power Management
+ intel_idle
+ cpufreq
+ intel_pstate
++ amd_pstate
+ cpufreq_drivers
+ 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
--- a/arch/x86/include/asm/cpufeatures.h
@@ -23,23 +751,6 @@ index d0ce5cfd3ac1..f7aea50e3371 100644
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
---
-2.33.0
-
-From 8180f01cf18d8ba79dac94a817294e85a8d84dc4 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Mon, 25 Jan 2021 15:50:24 +0800
-Subject: [PATCH 02/19] x86/msr: add AMD CPPC MSR definitions
-
-AMD CPPC (Collaborative Processor Performance Control) function uses MSR
-registers to manage the performance hints. So add the MSR register macro
-here.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- arch/x86/include/asm/msr-index.h | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index a7c413432b33..ce42e15cf303 100644
--- a/arch/x86/include/asm/msr-index.h
@@ -68,23 +779,6 @@ index a7c413432b33..ce42e15cf303 100644
/* Fam 17h MSRs */
#define MSR_F17H_IRPERF 0xc00000e9
---
-2.33.0
-
-From 8dc33d1590f80a60f12325e7c646a8551a41adf1 Mon Sep 17 00:00:00 2001
-From: Jinzhou Su <Jinzhou.Su@amd.com>
-Date: Mon, 9 Aug 2021 19:04:17 +0800
-Subject: [PATCH 03/19] ACPI: CPPC: add cppc enable register function
-
-Export the cppc enable register function for future use.
-
-Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/acpi/cppc_acpi.c | 42 ++++++++++++++++++++++++++++++++++++++++
- include/acpi/cppc_acpi.h | 5 +++++
- 2 files changed, 47 insertions(+)
-
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index a4d4eebba1da..de4b30545215 100644
--- a/drivers/acpi/cppc_acpi.c
@@ -138,154 +832,6 @@ index a4d4eebba1da..de4b30545215 100644
/**
* cppc_set_perf - Set a CPU's performance controls.
* @cpu: CPU for which to set performance controls.
-diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
-index 9f4985b4d64d..3fdae40a75fc 100644
---- a/include/acpi/cppc_acpi.h
-+++ b/include/acpi/cppc_acpi.h
-@@ -137,6 +137,7 @@ struct cppc_cpudata {
- extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
- extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
- extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
-+extern int cppc_set_enable(int cpu, u32 enable);
- extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
- extern bool acpi_cpc_valid(void);
- extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
-@@ -157,6 +158,10 @@ static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
- {
- return -ENOTSUPP;
- }
-+static inline int cppc_set_enable(int cpu, u32 enable)
-+{
-+ return -ENOTSUPP;
-+}
- static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
- {
- return -ENOTSUPP;
---
-2.33.0
-
-From df9ad0b99a9f0e3371aa94e49fe92a2c2a9fa95d Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Thu, 10 Jun 2021 18:04:45 +0800
-Subject: [PATCH 04/19] cpufreq: amd: introduce a new amd pstate driver to
- support future processors
-
-amd-pstate is the AMD CPU performance scaling driver that introduces a
-new CPU frequency control mechanism on AMD Zen based CPU series in Linux
-kernel. The new mechanism is based on Collaborative processor
-performance control (CPPC) which is finer grain frequency management
-than legacy ACPI hardware P-States. Current AMD CPU platforms are using
-the ACPI P-states driver to manage CPU frequency and clocks with
-switching only in 3 P-states. AMD P-States is to replace the ACPI
-P-states controls, allows a flexible, low-latency interface for the
-Linux kernel to directly communicate the performance hints to hardware.
-
-"amd-pstate" leverages the Linux kernel governors such as *schedutil*,
-*ondemand*, etc. to manage the performance hints which are provided by CPPC
-hardware functionality. The first version for amd-pstate is to support one
-of the Zen3 processors, and we will support more in future after we verify
-the hardware and SBIOS functionalities.
-
-There are two types of hardware implementations for amd-pstate: one is full
-MSR support and another is shared memory support. It can use
-X86_FEATURE_AMD_CPPC_EXT feature flag to distinguish the different types.
-
-Using the new AMD P-States method + kernel governors (*schedutil*,
-*ondemand*, ...) to manage the frequency update is the most appropriate
-bridge between AMD Zen based hardware processor and Linux kernel, the
-processor is able to ajust to the most efficiency frequency according to
-the kernel scheduler loading.
-
-Performance Per Watt (PPW) Caculation:
-
-The PPW caculation is referred by below paper:
-https://software.intel.com/content/dam/develop/external/us/en/documents/performance-per-what-paper.pdf
-
-Below formula is referred from below spec to measure the PPW:
-
-(F / t) / P = F * t / (t * E) = F / E,
-
-"F" is the number of frames per second.
-"P" is power measurd in watts.
-"E" is energy measured in joules.
-
-We use the RAPL interface with "perf" tool to get the energy data of the
-package power.
-
-The data comparsions between amd-pstate and acpi-freq module are tested on
-AMD Cezanne processor:
-
-1) TBench CPU benchmark:
-
-+---------------------------------------------------------------------+
-| |
-| TBench (Performance Per Watt) |
-| Higher is better |
-+-------------------+------------------------+------------------------+
-| | Performance Per Watt | Performance Per Watt |
-| Kernel Module | (Schedutil) | (Ondemand) |
-| | Unit: MB / (s * J) | Unit: MB / (s * J) |
-+-------------------+------------------------+------------------------+
-| | | |
-| acpi-cpufreq | 3.022 | 2.969 |
-| | | |
-+-------------------+------------------------+------------------------+
-| | | |
-| amd-pstate | 3.131 | 3.284 |
-| | | |
-+-------------------+------------------------+------------------------+
-
-2) Gitsource CPU benchmark:
-
-+---------------------------------------------------------------------+
-| |
-| Gitsource (Performance Per Watt) |
-| Higher is better |
-+-------------------+------------------------+------------------------+
-| | Performance Per Watt | Performance Per Watt |
-| Kernel Module | (Schedutil) | (Ondemand) |
-| | Unit: 1 / (s * J) | Unit: 1 / (s * J) |
-+-------------------+------------------------+------------------------+
-| | | |
-| acpi-cpufreq | 3.42172E-07 | 2.74508E-07 |
-| | | |
-+-------------------+------------------------+------------------------+
-| | | |
-| amd-pstate | 4.09141E-07 | 3.47610E-07 |
-| | | |
-+-------------------+------------------------+------------------------+
-
-3) Speedometer 2.0 CPU benchmark:
-
-+---------------------------------------------------------------------+
-| |
-| Speedometer 2.0 (Performance Per Watt) |
-| Higher is better |
-+-------------------+------------------------+------------------------+
-| | Performance Per Watt | Performance Per Watt |
-| Kernel Module | (Schedutil) | (Ondemand) |
-| | Unit: 1 / (s * J) | Unit: 1 / (s * J) |
-+-------------------+------------------------+------------------------+
-| | | |
-| acpi-cpufreq | 0.116111767 | 0.110321664 |
-| | | |
-+-------------------+------------------------+------------------------+
-| | | |
-| amd-pstate | 0.115825281 | 0.122024299 |
-| | | |
-+-------------------+------------------------+------------------------+
-
-According to above average data, we can see this solution has shown better
-performance per watt scaling on mobile CPU benchmarks in most of cases.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/Kconfig.x86 | 13 +
- drivers/cpufreq/Makefile | 1 +
- drivers/cpufreq/amd-pstate.c | 478 +++++++++++++++++++++++++++++++++++
- 3 files changed, 492 insertions(+)
- create mode 100644 drivers/cpufreq/amd-pstate.c
-
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 92701a18bdd9..9cd7e338bdcd 100644
--- a/drivers/cpufreq/Kconfig.x86
@@ -311,23 +857,144 @@ 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..3d4bd7141cf8 100644
+index 27d3bd7ea9d4..c1909475eaf9 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
-@@ -24,6 +24,7 @@ obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o
+@@ -17,6 +17,10 @@ obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o
+ obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o
+ obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o
+
++# Traces
++CFLAGS_amd-pstate-trace.o := -I$(src)
++amd_pstate-y := amd-pstate.o amd-pstate-trace.o
++
+ ##################################################################################
+ # 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.
# speedstep-* is preferred over p4-clockmod.
-+obj-$(CONFIG_X86_AMD_PSTATE) += amd-pstate.o
++obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
+diff --git a/drivers/cpufreq/amd-pstate-trace.c b/drivers/cpufreq/amd-pstate-trace.c
+new file mode 100644
+index 000000000000..891b696dcd69
+--- /dev/null
++++ b/drivers/cpufreq/amd-pstate-trace.c
+@@ -0,0 +1,2 @@
++#define CREATE_TRACE_POINTS
++#include "amd-pstate-trace.h"
+diff --git a/drivers/cpufreq/amd-pstate-trace.h b/drivers/cpufreq/amd-pstate-trace.h
+new file mode 100644
+index 000000000000..50c85e150f30
+--- /dev/null
++++ b/drivers/cpufreq/amd-pstate-trace.h
+@@ -0,0 +1,96 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * amd-pstate-trace.h - AMD Processor P-state Frequency Driver Tracer
++ *
++ * Copyright (C) 2021 Advanced Micro Devices, Inc. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ * Author: Huang Rui <ray.huang@amd.com>
++ */
++
++#if !defined(_AMD_PSTATE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _AMD_PSTATE_TRACE_H
++
++#include <linux/cpufreq.h>
++#include <linux/tracepoint.h>
++#include <linux/trace_events.h>
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM amd_cpu
++
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE amd-pstate-trace
++
++#define TPS(x) tracepoint_string(x)
++
++TRACE_EVENT(amd_pstate_perf,
++
++ TP_PROTO(unsigned long min_perf,
++ unsigned long target_perf,
++ unsigned long capacity,
++ unsigned int cpu_id,
++ u64 prev,
++ u64 value,
++ int type
++ ),
++
++ TP_ARGS(min_perf,
++ target_perf,
++ capacity,
++ cpu_id,
++ prev,
++ value,
++ type
++ ),
++
++ TP_STRUCT__entry(
++ __field(unsigned long, min_perf)
++ __field(unsigned long, target_perf)
++ __field(unsigned long, capacity)
++ __field(unsigned int, cpu_id)
++ __field(u64, prev)
++ __field(u64, value)
++ __field(int, type)
++ ),
++
++ TP_fast_assign(
++ __entry->min_perf = min_perf;
++ __entry->target_perf = target_perf;
++ __entry->capacity = capacity;
++ __entry->cpu_id = cpu_id;
++ __entry->prev = prev;
++ __entry->value = value;
++ __entry->type = type;
++ ),
++
++ TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu cpu_id=%u prev=0x%llx value=0x%llx type=0x%d",
++ (unsigned long)__entry->min_perf,
++ (unsigned long)__entry->target_perf,
++ (unsigned long)__entry->capacity,
++ (unsigned int)__entry->cpu_id,
++ (u64)__entry->prev,
++ (u64)__entry->value,
++ (int)__entry->type
++ )
++);
++
++#endif /* _AMD_PSTATE_TRACE_H */
++
++/* This part must be outside protection */
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH .
++
++#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..4c9c9bf1d72b
+index 000000000000..9c60388d45ed
--- /dev/null
+++ b/drivers/cpufreq/amd-pstate.c
-@@ -0,0 +1,478 @@
+@@ -0,0 +1,812 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * amd-pstate.c - AMD Processor P-state Frequency Driver
@@ -374,10 +1041,18 @@ index 000000000000..4c9c9bf1d72b
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+#include <asm/cpu_device_id.h>
++#include "amd-pstate-trace.h"
+
+#define AMD_PSTATE_TRANSITION_LATENCY 0x20000
+#define AMD_PSTATE_TRANSITION_DELAY 500
+
++enum switch_type
++{
++ AMD_TARGET = 0,
++ AMD_ADJUST_PERF,
++ AMD_FAST_SWITCH,
++};
++
+static struct cpufreq_driver amd_pstate_driver;
+
+struct amd_cpudata {
@@ -397,6 +1072,8 @@ index 000000000000..4c9c9bf1d72b
+ u32 min_freq;
+ u32 nominal_freq;
+ u32 lowest_nonlinear_freq;
++
++ bool boost_supported;
+};
+
+struct amd_pstate_perf_funcs {
@@ -412,6 +1089,19 @@ index 000000000000..4c9c9bf1d72b
+ return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable ? 1 : 0);
+}
+
++static int cppc_enable(bool enable)
++{
++ int cpu, ret = 0;
++
++ for_each_online_cpu(cpu) {
++ ret = cppc_set_enable(cpu, enable ? 1 : 0);
++ if (ret)
++ return ret;
++ }
++
++ return ret;
++}
++
+static int
+amd_pstate_enable(struct amd_pstate_perf_funcs *funcs, bool enable)
+{
@@ -443,6 +1133,24 @@ index 000000000000..4c9c9bf1d72b
+ return 0;
+}
+
++static int cppc_init_perf(struct amd_cpudata *cpudata)
++{
++ struct cppc_perf_caps cppc_perf;
++
++ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
++ if (ret)
++ return ret;
++
++ WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
++
++ WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
++ WRITE_ONCE(cpudata->lowest_nonlinear_perf,
++ cppc_perf.lowest_nonlinear_perf);
++ WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf);
++
++ return 0;
++}
++
+static int amd_pstate_init_perf(struct amd_cpudata *cpudata)
+{
+ struct amd_pstate_perf_funcs *funcs = cpufreq_get_driver_data();
@@ -464,6 +1172,19 @@ index 000000000000..4c9c9bf1d72b
+ READ_ONCE(cpudata->cppc_req_cached));
+}
+
++static void cppc_update_perf(struct amd_cpudata *cpudata,
++ u32 min_perf, u32 des_perf,
++ u32 max_perf, bool fast_switch)
++{
++ struct cppc_perf_ctrls perf_ctrls;
++
++ perf_ctrls.max_perf = max_perf;
++ perf_ctrls.min_perf = min_perf;
++ perf_ctrls.desired_perf = des_perf;
++
++ cppc_set_perf(cpudata->cpu, &perf_ctrls);
++}
++
+static int
+amd_pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
+ u32 des_perf, u32 max_perf, bool fast_switch)
@@ -481,7 +1202,8 @@ index 000000000000..4c9c9bf1d72b
+
+static int
+amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
-+ u32 des_perf, u32 max_perf, bool fast_switch)
++ u32 des_perf, u32 max_perf, bool fast_switch,
++ enum switch_type type)
+{
+ u64 prev = READ_ONCE(cpudata->cppc_req_cached);
+ u64 value = prev;
@@ -495,6 +1217,8 @@ index 000000000000..4c9c9bf1d72b
+ value &= ~REQ_MAX_PERF(~0L);
+ value |= REQ_MAX_PERF(max_perf);
+
++ trace_amd_pstate_perf(min_perf, des_perf, max_perf,
++ cpudata->cpu, prev, value, type);
+ if (value == prev)
+ return 0;
+
@@ -504,6 +1228,19 @@ index 000000000000..4c9c9bf1d72b
+ 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;
++}
++
+static int amd_pstate_verify(struct cpufreq_policy_data *policy)
+{
+ cpufreq_verify_within_cpu_limits(policy);
@@ -536,12 +1273,72 @@ index 000000000000..4c9c9bf1d72b
+
+ cpufreq_freq_transition_begin(policy, &freqs);
+ ret = amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-+ amd_max_perf, false);
++ amd_max_perf, false, AMD_TARGET);
+ cpufreq_freq_transition_end(policy, &freqs, false);
+
+ return ret;
+}
+
++static void amd_pstate_adjust_perf(unsigned int cpu,
++ unsigned long min_perf,
++ unsigned long target_perf,
++ unsigned long capacity)
++{
++ unsigned long amd_max_perf, amd_min_perf, amd_des_perf,
++ amd_cap_perf, lowest_nonlinear_perf;
++ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
++ struct amd_cpudata *cpudata = policy->driver_data;
++
++ amd_cap_perf = READ_ONCE(cpudata->highest_perf);
++ lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
++
++ if (target_perf < capacity)
++ amd_des_perf = DIV_ROUND_UP(amd_cap_perf * target_perf,
++ capacity);
++
++ amd_min_perf = READ_ONCE(cpudata->highest_perf);
++ if (min_perf < capacity)
++ amd_min_perf = DIV_ROUND_UP(amd_cap_perf * min_perf, capacity);
++
++ if (amd_min_perf < lowest_nonlinear_perf)
++ amd_min_perf = lowest_nonlinear_perf;
++
++ amd_max_perf = amd_cap_perf;
++ if (amd_max_perf < amd_min_perf)
++ amd_max_perf = amd_min_perf;
++
++ amd_des_perf = clamp_t(unsigned long, amd_des_perf,
++ 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;
++}
++
+static int amd_get_min_freq(struct amd_cpudata *cpudata)
+{
+ struct cppc_perf_caps cppc_perf;
@@ -617,6 +1414,37 @@ index 000000000000..4c9c9bf1d72b
+ return lowest_nonlinear_freq * 1000;
+}
+
++static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
++{
++ struct amd_cpudata *cpudata = policy->driver_data;
++ int ret;
++
++ if (!cpudata->boost_supported) {
++ pr_err("Boost mode is not supported by this processor or SBIOS\n");
++ return -EINVAL;
++ }
++
++ if (state)
++ policy->cpuinfo.max_freq = cpudata->max_freq;
++ else
++ policy->cpuinfo.max_freq = cpudata->nominal_freq;
++
++ policy->max = policy->cpuinfo.max_freq;
++
++ ret = freq_qos_update_request(&cpudata->req[1],
++ policy->cpuinfo.max_freq);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
++{
++ cpudata->boost_supported = true;
++ amd_pstate_driver.boost_enabled = true;
++}
++
+static int amd_pstate_init_freqs_in_cpudata(struct amd_cpudata *cpudata,
+ u32 max_freq, u32 min_freq,
+ u32 nominal_freq,
@@ -640,6 +1468,12 @@ index 000000000000..4c9c9bf1d72b
+ .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;
@@ -686,6 +1520,9 @@ index 000000000000..4c9c9bf1d72b
+ /* It will be updated by governor */
+ policy->cur = policy->cpuinfo.min_freq;
+
++ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT))
++ policy->fast_switch_possible = true;
++
+ ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
+ FREQ_QOS_MIN, policy->cpuinfo.min_freq);
+ if (ret < 0) {
@@ -710,6 +1547,9 @@ index 000000000000..4c9c9bf1d72b
+
+ policy->driver_data = cpudata;
+
++ if (amd_pstate_boost_supported(cpudata))
++ amd_pstate_boost_init(cpudata);
++
+ return 0;
+
+free_cpudata3:
@@ -734,730 +1574,10 @@ index 000000000000..4c9c9bf1d72b
+ return 0;
+}
+
-+static struct cpufreq_driver amd_pstate_driver = {
-+ .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
-+ .verify = amd_pstate_verify,
-+ .target = amd_pstate_target,
-+ .init = amd_pstate_cpu_init,
-+ .exit = amd_pstate_cpu_exit,
-+ .name = "amd-pstate",
-+};
-+
-+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;
-+
-+ if (!acpi_cpc_valid()) {
-+ pr_debug("%s, the _CPC object is not present in SBIOS\n",
-+ __func__);
-+ return -ENODEV;
-+ }
-+
-+ /* don't keep reloading if cpufreq_driver exists */
-+ if (cpufreq_get_current_driver())
-+ return -EEXIST;
-+
-+ /* capability check */
-+ if (!boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT)) {
-+ pr_debug("%s, AMD CPPC extension functionality is supported\n",
-+ __func__);
-+ return -ENODEV;
-+ }
-+
-+ funcs = &pstate_funcs;
-+
-+ /* enable amd pstate feature */
-+ ret = amd_pstate_enable(funcs, 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);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+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);
-+}
-+
-+module_init(amd_pstate_init);
-+module_exit(amd_pstate_exit);
-+
-+MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
-+MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
-+MODULE_LICENSE("GPL");
---
-2.33.0
-
-From 54beca4738acc38c08710cfcb1c3312755000cf6 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Fri, 13 Aug 2021 18:43:47 +0800
-Subject: [PATCH 05/19] cpufreq: amd: add fast switch function for amd-pstate
- module
-
-Introduce the fast switch function for amd-pstate module on the AMD
-processors which support the full MSR register control. It's able to
-decrease the lattency on interrupt context.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/amd-pstate.c | 64 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 64 insertions(+)
-
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index 4c9c9bf1d72b..32b4f6d79783 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -212,6 +212,66 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
- return ret;
- }
-
-+static void amd_pstate_adjust_perf(unsigned int cpu,
-+ unsigned long min_perf,
-+ unsigned long target_perf,
-+ unsigned long capacity)
-+{
-+ unsigned long amd_max_perf, amd_min_perf, amd_des_perf,
-+ amd_cap_perf, lowest_nonlinear_perf;
-+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-+ struct amd_cpudata *cpudata = policy->driver_data;
-+
-+ amd_cap_perf = READ_ONCE(cpudata->highest_perf);
-+ lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
-+
-+ if (target_perf < capacity)
-+ amd_des_perf = DIV_ROUND_UP(amd_cap_perf * target_perf,
-+ capacity);
-+
-+ amd_min_perf = READ_ONCE(cpudata->highest_perf);
-+ if (min_perf < capacity)
-+ amd_min_perf = DIV_ROUND_UP(amd_cap_perf * min_perf, capacity);
-+
-+ if (amd_min_perf < lowest_nonlinear_perf)
-+ amd_min_perf = lowest_nonlinear_perf;
-+
-+ amd_max_perf = amd_cap_perf;
-+ if (amd_max_perf < amd_min_perf)
-+ amd_max_perf = amd_min_perf;
-+
-+ amd_des_perf = clamp_t(unsigned long, amd_des_perf,
-+ amd_min_perf, amd_max_perf);
-+
-+ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-+ amd_max_perf, true);
-+}
-+
-+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);
-+
-+ 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;
-+}
-+
- static int amd_get_min_freq(struct amd_cpudata *cpudata)
- {
- struct cppc_perf_caps cppc_perf;
-@@ -356,6 +416,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
- /* It will be updated by governor */
- policy->cur = policy->cpuinfo.min_freq;
-
-+ policy->fast_switch_possible = true;
-+
- ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
- FREQ_QOS_MIN, policy->cpuinfo.min_freq);
- if (ret < 0) {
-@@ -408,6 +470,8 @@ static struct cpufreq_driver amd_pstate_driver = {
- .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
- .verify = amd_pstate_verify,
- .target = amd_pstate_target,
-+ .fast_switch = amd_pstate_fast_switch,
-+ .adjust_perf = amd_pstate_adjust_perf,
- .init = amd_pstate_cpu_init,
- .exit = amd_pstate_cpu_exit,
- .name = "amd-pstate",
---
-2.33.0
-
-From ad7cc7a238ee889b9001d95fef83172763b95939 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Mon, 9 Aug 2021 19:06:51 +0800
-Subject: [PATCH 06/19] cpufreq: amd: add acpi cppc function as the backend for
- legacy processors
-
-In some old Zen based processors, they are using the shared memory that
-exposed from ACPI SBIOS.
-
-Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/amd-pstate.c | 63 ++++++++++++++++++++++++++++++++----
- 1 file changed, 57 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index 32b4f6d79783..a46cd5dd9f7c 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -82,6 +82,19 @@ static inline int pstate_enable(bool enable)
- return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable ? 1 : 0);
- }
-
-+static int cppc_enable(bool enable)
-+{
-+ int cpu, ret = 0;
-+
-+ for_each_online_cpu(cpu) {
-+ ret = cppc_set_enable(cpu, enable ? 1 : 0);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return ret;
-+}
-+
- static int
- amd_pstate_enable(struct amd_pstate_perf_funcs *funcs, bool enable)
- {
-@@ -113,6 +126,24 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
- return 0;
- }
-
-+static int cppc_init_perf(struct amd_cpudata *cpudata)
-+{
-+ struct cppc_perf_caps cppc_perf;
-+
-+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-+ if (ret)
-+ return ret;
-+
-+ WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
-+
-+ WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
-+ WRITE_ONCE(cpudata->lowest_nonlinear_perf,
-+ cppc_perf.lowest_nonlinear_perf);
-+ WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf);
-+
-+ return 0;
-+}
-+
- static int amd_pstate_init_perf(struct amd_cpudata *cpudata)
- {
- struct amd_pstate_perf_funcs *funcs = cpufreq_get_driver_data();
-@@ -134,6 +165,19 @@ static void pstate_update_perf(struct amd_cpudata *cpudata,
- READ_ONCE(cpudata->cppc_req_cached));
- }
-
-+static void cppc_update_perf(struct amd_cpudata *cpudata,
-+ u32 min_perf, u32 des_perf,
-+ u32 max_perf, bool fast_switch)
-+{
-+ struct cppc_perf_ctrls perf_ctrls;
-+
-+ perf_ctrls.max_perf = max_perf;
-+ perf_ctrls.min_perf = min_perf;
-+ perf_ctrls.desired_perf = des_perf;
-+
-+ cppc_set_perf(cpudata->cpu, &perf_ctrls);
-+}
-+
- static int
- amd_pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
- u32 des_perf, u32 max_perf, bool fast_switch)
-@@ -370,6 +414,12 @@ static struct amd_pstate_perf_funcs pstate_funcs = {
- .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;
-@@ -416,7 +466,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
- /* It will be updated by governor */
- policy->cur = policy->cpuinfo.min_freq;
-
-- policy->fast_switch_possible = true;
-+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT))
-+ policy->fast_switch_possible = true;
-
- ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
- FREQ_QOS_MIN, policy->cpuinfo.min_freq);
-@@ -471,7 +522,6 @@ static struct cpufreq_driver amd_pstate_driver = {
- .verify = amd_pstate_verify,
- .target = amd_pstate_target,
- .fast_switch = amd_pstate_fast_switch,
-- .adjust_perf = amd_pstate_adjust_perf,
- .init = amd_pstate_cpu_init,
- .exit = amd_pstate_cpu_exit,
- .name = "amd-pstate",
-@@ -496,14 +546,15 @@ static int __init amd_pstate_init(void)
- return -EEXIST;
-
- /* capability check */
-- if (!boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT)) {
-+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT)) {
- pr_debug("%s, AMD CPPC extension functionality is supported\n",
- __func__);
-- return -ENODEV;
-+ funcs = &pstate_funcs;
-+ amd_pstate_driver.adjust_perf = amd_pstate_adjust_perf;
-+ } else {
-+ funcs = &cppc_funcs;
- }
-
-- funcs = &pstate_funcs;
--
- /* enable amd pstate feature */
- ret = amd_pstate_enable(funcs, true);
- if (ret) {
---
-2.33.0
-
-From e007c18166d11d78757454ebfac967ae460ebf08 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Thu, 10 Jun 2021 20:24:00 +0800
-Subject: [PATCH 07/19] cpufreq: amd: add trace for amd-pstate module
-
-Add trace event to monitor the performance value changes which is
-controlled by cpu governors.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/Makefile | 6 +-
- drivers/cpufreq/amd-pstate-trace.c | 2 +
- drivers/cpufreq/amd-pstate-trace.h | 96 ++++++++++++++++++++++++++++++
- drivers/cpufreq/amd-pstate.c | 19 ++++--
- 4 files changed, 118 insertions(+), 5 deletions(-)
- create mode 100644 drivers/cpufreq/amd-pstate-trace.c
- create mode 100644 drivers/cpufreq/amd-pstate-trace.h
-
-diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
-index 3d4bd7141cf8..c1909475eaf9 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
- obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o
- obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o
-
-+# Traces
-+CFLAGS_amd-pstate-trace.o := -I$(src)
-+amd_pstate-y := amd-pstate.o amd-pstate-trace.o
-+
- ##################################################################################
- # x86 drivers.
- # Link order matters. K8 is preferred to ACPI because of firmware bugs in early
-@@ -24,7 +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.
- # speedstep-* is preferred over p4-clockmod.
-
--obj-$(CONFIG_X86_AMD_PSTATE) += amd-pstate.o
-+obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o
- obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
- obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
- obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
-diff --git a/drivers/cpufreq/amd-pstate-trace.c b/drivers/cpufreq/amd-pstate-trace.c
-new file mode 100644
-index 000000000000..891b696dcd69
---- /dev/null
-+++ b/drivers/cpufreq/amd-pstate-trace.c
-@@ -0,0 +1,2 @@
-+#define CREATE_TRACE_POINTS
-+#include "amd-pstate-trace.h"
-diff --git a/drivers/cpufreq/amd-pstate-trace.h b/drivers/cpufreq/amd-pstate-trace.h
-new file mode 100644
-index 000000000000..50c85e150f30
---- /dev/null
-+++ b/drivers/cpufreq/amd-pstate-trace.h
-@@ -0,0 +1,96 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * amd-pstate-trace.h - AMD Processor P-state Frequency Driver Tracer
-+ *
-+ * Copyright (C) 2021 Advanced Micro Devices, Inc. All Rights Reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version 2
-+ * of the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along with
-+ * this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-+ *
-+ * Author: Huang Rui <ray.huang@amd.com>
-+ */
-+
-+#if !defined(_AMD_PSTATE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
-+#define _AMD_PSTATE_TRACE_H
-+
-+#include <linux/cpufreq.h>
-+#include <linux/tracepoint.h>
-+#include <linux/trace_events.h>
-+
-+#undef TRACE_SYSTEM
-+#define TRACE_SYSTEM amd_cpu
-+
-+#undef TRACE_INCLUDE_FILE
-+#define TRACE_INCLUDE_FILE amd-pstate-trace
-+
-+#define TPS(x) tracepoint_string(x)
-+
-+TRACE_EVENT(amd_pstate_perf,
-+
-+ TP_PROTO(unsigned long min_perf,
-+ unsigned long target_perf,
-+ unsigned long capacity,
-+ unsigned int cpu_id,
-+ u64 prev,
-+ u64 value,
-+ int type
-+ ),
-+
-+ TP_ARGS(min_perf,
-+ target_perf,
-+ capacity,
-+ cpu_id,
-+ prev,
-+ value,
-+ type
-+ ),
-+
-+ TP_STRUCT__entry(
-+ __field(unsigned long, min_perf)
-+ __field(unsigned long, target_perf)
-+ __field(unsigned long, capacity)
-+ __field(unsigned int, cpu_id)
-+ __field(u64, prev)
-+ __field(u64, value)
-+ __field(int, type)
-+ ),
-+
-+ TP_fast_assign(
-+ __entry->min_perf = min_perf;
-+ __entry->target_perf = target_perf;
-+ __entry->capacity = capacity;
-+ __entry->cpu_id = cpu_id;
-+ __entry->prev = prev;
-+ __entry->value = value;
-+ __entry->type = type;
-+ ),
-+
-+ TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu cpu_id=%u prev=0x%llx value=0x%llx type=0x%d",
-+ (unsigned long)__entry->min_perf,
-+ (unsigned long)__entry->target_perf,
-+ (unsigned long)__entry->capacity,
-+ (unsigned int)__entry->cpu_id,
-+ (u64)__entry->prev,
-+ (u64)__entry->value,
-+ (int)__entry->type
-+ )
-+);
-+
-+#endif /* _AMD_PSTATE_TRACE_H */
-+
-+/* This part must be outside protection */
-+#undef TRACE_INCLUDE_PATH
-+#define TRACE_INCLUDE_PATH .
-+
-+#include <trace/define_trace.h>
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index a46cd5dd9f7c..ea965a122431 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -44,10 +44,18 @@
- #include <asm/processor.h>
- #include <asm/cpufeature.h>
- #include <asm/cpu_device_id.h>
-+#include "amd-pstate-trace.h"
-
- #define AMD_PSTATE_TRANSITION_LATENCY 0x20000
- #define AMD_PSTATE_TRANSITION_DELAY 500
-
-+enum switch_type
-+{
-+ AMD_TARGET = 0,
-+ AMD_ADJUST_PERF,
-+ AMD_FAST_SWITCH,
-+};
-+
- static struct cpufreq_driver amd_pstate_driver;
-
- struct amd_cpudata {
-@@ -195,7 +203,8 @@ amd_pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
-
- static int
- amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
-- u32 des_perf, u32 max_perf, bool fast_switch)
-+ u32 des_perf, u32 max_perf, bool fast_switch,
-+ enum switch_type type)
- {
- u64 prev = READ_ONCE(cpudata->cppc_req_cached);
- u64 value = prev;
-@@ -209,6 +218,8 @@ amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
- value &= ~REQ_MAX_PERF(~0L);
- value |= REQ_MAX_PERF(max_perf);
-
-+ trace_amd_pstate_perf(min_perf, des_perf, max_perf,
-+ cpudata->cpu, prev, value, type);
- if (value == prev)
- return 0;
-
-@@ -250,7 +261,7 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
-
- cpufreq_freq_transition_begin(policy, &freqs);
- ret = amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-- amd_max_perf, false);
-+ amd_max_perf, false, AMD_TARGET);
- cpufreq_freq_transition_end(policy, &freqs, false);
-
- return ret;
-@@ -288,7 +299,7 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
- amd_min_perf, amd_max_perf);
-
- amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-- amd_max_perf, true);
-+ amd_max_perf, true, AMD_ADJUST_PERF);
- }
-
- static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy,
-@@ -308,7 +319,7 @@ static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy,
- cpudata->max_freq);
-
- amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-- amd_max_perf, true);
-+ 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);
---
-2.33.0
-
-From 24ab2966561da669b9879a6167e2cc7e5929735c Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Thu, 10 Jun 2021 23:13:00 +0800
-Subject: [PATCH 08/19] cpufreq: amd: add boost mode support for amd-pstate
-
-If the sbios supports the boost mode of amd-pstate, let's switch to
-boost enabled by default.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/amd-pstate.c | 50 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 50 insertions(+)
-
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index ea965a122431..67a9a117f524 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -75,6 +75,8 @@ struct amd_cpudata {
- u32 min_freq;
- u32 nominal_freq;
- u32 lowest_nonlinear_freq;
-+
-+ bool boost_supported;
- };
-
- struct amd_pstate_perf_funcs {
-@@ -229,6 +231,19 @@ amd_pstate_update(struct amd_cpudata *cpudata, u32 min_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;
-+}
-+
- static int amd_pstate_verify(struct cpufreq_policy_data *policy)
- {
- cpufreq_verify_within_cpu_limits(policy);
-@@ -402,6 +417,37 @@ static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata)
- return lowest_nonlinear_freq * 1000;
- }
-
-+static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
-+{
-+ struct amd_cpudata *cpudata = policy->driver_data;
-+ int ret;
-+
-+ if (!cpudata->boost_supported) {
-+ pr_err("Boost mode is not supported by this processor or SBIOS\n");
-+ return -EINVAL;
-+ }
-+
-+ if (state)
-+ policy->cpuinfo.max_freq = cpudata->max_freq;
-+ else
-+ policy->cpuinfo.max_freq = cpudata->nominal_freq;
-+
-+ policy->max = policy->cpuinfo.max_freq;
-+
-+ ret = freq_qos_update_request(&cpudata->req[1],
-+ policy->cpuinfo.max_freq);
-+ if (ret < 0)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
-+{
-+ cpudata->boost_supported = true;
-+ amd_pstate_driver.boost_enabled = true;
-+}
-+
- static int amd_pstate_init_freqs_in_cpudata(struct amd_cpudata *cpudata,
- u32 max_freq, u32 min_freq,
- u32 nominal_freq,
-@@ -504,6 +550,9 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
-
- policy->driver_data = cpudata;
-
-+ if (amd_pstate_boost_supported(cpudata))
-+ amd_pstate_boost_init(cpudata);
-+
- return 0;
-
- free_cpudata3:
-@@ -535,6 +584,7 @@ static struct cpufreq_driver amd_pstate_driver = {
- .fast_switch = amd_pstate_fast_switch,
- .init = amd_pstate_cpu_init,
- .exit = amd_pstate_cpu_exit,
-+ .set_boost = amd_pstate_set_boost,
- .name = "amd-pstate",
- };
-
---
-2.33.0
-
-From fdbec5a44fab1213e459312b542e27dc0181d7e4 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sat, 19 Jun 2021 23:41:30 +0800
-Subject: [PATCH 09/19] cpufreq: amd: add amd-pstate checking support check
- attribute
-
-The amd-pstate hardware support check will be needed by cpupower to know
-whether amd-pstate is enabled and supported.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/amd-pstate.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index 67a9a117f524..48dedd5af101 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -577,6 +577,19 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
- return 0;
- }
-
-+static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy,
-+ char *buf)
-+{
-+ return sprintf(&buf[0], "%d\n", acpi_cpc_valid() ? 1 : 0);
-+}
-+
-+cpufreq_freq_attr_ro(is_amd_pstate_enabled);
-+
-+static struct freq_attr *amd_pstate_attr[] = {
-+ &is_amd_pstate_enabled,
-+ NULL,
-+};
-+
- static struct cpufreq_driver amd_pstate_driver = {
- .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
- .verify = amd_pstate_verify,
-@@ -586,6 +599,7 @@ static struct cpufreq_driver amd_pstate_driver = {
- .exit = amd_pstate_cpu_exit,
- .set_boost = amd_pstate_set_boost,
- .name = "amd-pstate",
-+ .attr = amd_pstate_attr,
- };
-
- static int __init amd_pstate_init(void)
---
-2.33.0
-
-From 4043d05067a68c58255a6759c528bb78db656327 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sun, 20 Jun 2021 13:26:01 +0800
-Subject: [PATCH 10/19] cpufreq: amd: add amd-pstate frequencies attributes
-
-Introduce sysfs attributes to get the different level processor
-frequencies.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/amd-pstate.c | 80 +++++++++++++++++++++++++++++++++++-
- 1 file changed, 79 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index 48dedd5af101..3c727a22cb69 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -577,16 +577,94 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
- return 0;
- }
-
--static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy,
+/* Sysfs attributes */
+
+static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy,
- char *buf)
++ char *buf)
+{
+ int ret = 0, max_freq;
+ struct amd_cpudata *cpudata;
@@ -1524,51 +1644,6 @@ index 48dedd5af101..3c727a22cb69 100644
+ return ret;
+}
+
-+static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy,
-+ char *buf)
- {
- return sprintf(&buf[0], "%d\n", acpi_cpc_valid() ? 1 : 0);
- }
-
- cpufreq_freq_attr_ro(is_amd_pstate_enabled);
-+cpufreq_freq_attr_ro(amd_pstate_max_freq);
-+cpufreq_freq_attr_ro(amd_pstate_nominal_freq);
-+cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
-+cpufreq_freq_attr_ro(amd_pstate_min_freq);
-
- static struct freq_attr *amd_pstate_attr[] = {
- &is_amd_pstate_enabled,
-+ &amd_pstate_max_freq,
-+ &amd_pstate_nominal_freq,
-+ &amd_pstate_lowest_nonlinear_freq,
-+ &amd_pstate_min_freq,
- NULL,
- };
-
---
-2.33.0
-
-From 4b56a82d37ecb8e9f9df2d0b055939577ff147cf Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sun, 20 Jun 2021 15:01:08 +0800
-Subject: [PATCH 11/19] cpufreq: amd: add amd-pstate performance attributes
-
-Introduce sysfs attributes to get the different level amd-pstate
-performances.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- drivers/cpufreq/amd-pstate.c | 66 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 66 insertions(+)
-
-diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
-index 3c727a22cb69..9c60388d45ed 100644
---- a/drivers/cpufreq/amd-pstate.c
-+++ b/drivers/cpufreq/amd-pstate.c
-@@ -647,6 +647,62 @@ static ssize_t show_amd_pstate_min_freq(struct cpufreq_policy *policy, char *buf
- return ret;
- }
-
+static ssize_t
+show_amd_pstate_highest_perf(struct cpufreq_policy *policy, char *buf)
+{
@@ -1625,187 +1700,138 @@ index 3c727a22cb69..9c60388d45ed 100644
+ return ret;
+}
+
- static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy,
- char *buf)
- {
-@@ -654,17 +710,27 @@ static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy,
- }
-
- cpufreq_freq_attr_ro(is_amd_pstate_enabled);
++static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy,
++ char *buf)
++{
++ return sprintf(&buf[0], "%d\n", acpi_cpc_valid() ? 1 : 0);
++}
++
++cpufreq_freq_attr_ro(is_amd_pstate_enabled);
++
++cpufreq_freq_attr_ro(amd_pstate_max_freq);
++cpufreq_freq_attr_ro(amd_pstate_nominal_freq);
++cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
++cpufreq_freq_attr_ro(amd_pstate_min_freq);
+
- cpufreq_freq_attr_ro(amd_pstate_max_freq);
- cpufreq_freq_attr_ro(amd_pstate_nominal_freq);
- cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
- cpufreq_freq_attr_ro(amd_pstate_min_freq);
-
+cpufreq_freq_attr_ro(amd_pstate_highest_perf);
+cpufreq_freq_attr_ro(amd_pstate_nominal_perf);
+cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_perf);
+cpufreq_freq_attr_ro(amd_pstate_lowest_perf);
+
- static struct freq_attr *amd_pstate_attr[] = {
- &is_amd_pstate_enabled,
- &amd_pstate_max_freq,
- &amd_pstate_nominal_freq,
- &amd_pstate_lowest_nonlinear_freq,
- &amd_pstate_min_freq,
++static struct freq_attr *amd_pstate_attr[] = {
++ &is_amd_pstate_enabled,
++ &amd_pstate_max_freq,
++ &amd_pstate_nominal_freq,
++ &amd_pstate_lowest_nonlinear_freq,
++ &amd_pstate_min_freq,
+ &amd_pstate_highest_perf,
+ &amd_pstate_nominal_perf,
+ &amd_pstate_lowest_nonlinear_perf,
+ &amd_pstate_lowest_perf,
- NULL,
- };
-
---
-2.33.0
-
-From 5b16452c4363a46a28bd65a00a4a3282bdb7ec69 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Mon, 14 Jun 2021 22:52:01 +0800
-Subject: [PATCH 12/19] cpupower: add AMD P-state capability flag
-
-Add AMD P-state capability flag in cpupower to indicate AMD new P-state
-kernel module support on Ryzen processors.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- tools/power/cpupower/utils/helpers/helpers.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
-index 33ffacee7fcb..b4813efdfb00 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,
- #define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100
- #define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200
- #define CPUPOWER_CAP_AMD_CPB_MSR 0x00000400
-+#define CPUPOWER_CAP_AMD_PSTATE 0x00000800
-
- #define CPUPOWER_AMD_CPBDIS 0x02000000
-
---
-2.33.0
-
-From 456b88736d16414c3cce9dd5101b05dfe38baa18 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sun, 27 Jun 2021 22:25:39 +0800
-Subject: [PATCH 13/19] cpupower: add the function to check amd-pstate enabled
-
-Introduce the cpupower_amd_pstate_enabled() to check whether the kernel
-mode enables amd-pstate.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- tools/power/cpupower/utils/helpers/helpers.h | 5 +++++
- tools/power/cpupower/utils/helpers/misc.c | 20 ++++++++++++++++++++
- 2 files changed, 25 insertions(+)
-
-diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
-index b4813efdfb00..eb43c14d1728 100644
---- a/tools/power/cpupower/utils/helpers/helpers.h
-+++ b/tools/power/cpupower/utils/helpers/helpers.h
-@@ -136,6 +136,11 @@ 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 **************************/
++ NULL,
++};
+
-+extern unsigned long cpupower_amd_pstate_enabled(unsigned int cpu);
++static struct cpufreq_driver amd_pstate_driver = {
++ .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,
++ .name = "amd-pstate",
++ .attr = amd_pstate_attr,
++};
+
- /*
- * 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..07d80775fb68 100644
---- a/tools/power/cpupower/utils/helpers/misc.c
-+++ b/tools/power/cpupower/utils/helpers/misc.c
-@@ -83,6 +83,26 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val)
- return 0;
- }
-
-+unsigned long cpupower_amd_pstate_enabled(unsigned int cpu)
++static int __init amd_pstate_init(void)
+{
-+ char linebuf[MAX_LINE_LEN];
-+ char path[SYSFS_PATH_MAX];
-+ unsigned long val;
-+ char *endp;
++ int ret;
++ struct amd_pstate_perf_funcs *funcs;
+
-+ snprintf(path, sizeof(path),
-+ PATH_TO_CPU "cpu%u/cpufreq/is_amd_pstate_enabled", cpu);
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
++ return -ENODEV;
+
-+ if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0)
-+ return 0;
++ if (!acpi_cpc_valid()) {
++ pr_debug("%s, the _CPC object is not present in SBIOS\n",
++ __func__);
++ return -ENODEV;
++ }
+
-+ val = strtoul(linebuf, &endp, 0);
-+ if (endp == linebuf || errno == ERANGE)
-+ return 0;
++ /* don't keep reloading if cpufreq_driver exists */
++ if (cpufreq_get_current_driver())
++ return -EEXIST;
+
-+ return val;
++ /* capability check */
++ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT)) {
++ pr_debug("%s, AMD CPPC extension functionality is supported\n",
++ __func__);
++ funcs = &pstate_funcs;
++ amd_pstate_driver.adjust_perf = amd_pstate_adjust_perf;
++ } else {
++ funcs = &cppc_funcs;
++ }
++
++ /* enable amd pstate feature */
++ ret = amd_pstate_enable(funcs, 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);
++ return ret;
++ }
++
++ return 0;
+}
+
- #endif /* #if defined(__i386__) || defined(__x86_64__) */
-
- /* get_cpustate
---
-2.33.0
-
-From 9537cd2a2aa718faba5d61c1196d7b05c52a89f4 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sun, 27 Jun 2021 22:40:14 +0800
-Subject: [PATCH 14/19] cpupower: initial AMD P-state capability
-
-If kernel enables AMD P-state, cpupower won't need to respond ACPI
-hardware P-states function anymore.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- tools/power/cpupower/utils/helpers/cpuid.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
-index 72eb43593180..78218c54acca 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)
- if (ext_cpuid_level >= 0x80000008 &&
- cpuid_ebx(0x80000008) & (1 << 4))
- cpu_info->caps |= CPUPOWER_CAP_AMD_RDPRU;
++static void __exit amd_pstate_exit(void)
++{
++ struct amd_pstate_perf_funcs *funcs;
+
-+ if (cpupower_amd_pstate_enabled(0)) {
-+ cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE;
++ funcs = cpufreq_get_driver_data();
+
-+ /*
-+ * If AMD P-state is enabled, the firmware will treat
-+ * AMD P-state function as high priority.
-+ */
-+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB;
-+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB_MSR;
-+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_HW_PSTATE;
-+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_PSTATEDEF;
-+ }
- }
-
- if (cpu_info->vendor == X86_VENDOR_INTEL) {
---
-2.33.0
-
-From d3f392c951479c73e5a4b0c8d94901aafd5b9da7 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sun, 20 Jun 2021 17:07:25 +0800
-Subject: [PATCH 15/19] cpupower: add amd-pstate sysfs entries into libcpufreq
-
-These amd-pstate sysfs entries will be used on cpupower for amd-pstate
-kernel module.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- tools/power/cpupower/lib/cpufreq.c | 18 +++++++++++++++++-
- 1 file changed, 17 insertions(+), 1 deletion(-)
-
++ cpufreq_unregister_driver(&amd_pstate_driver);
++
++ amd_pstate_enable(funcs, false);
++}
++
++module_init(amd_pstate_init);
++module_exit(amd_pstate_exit);
++
++MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
++MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
+index 9f4985b4d64d..3fdae40a75fc 100644
+--- a/include/acpi/cppc_acpi.h
++++ b/include/acpi/cppc_acpi.h
+@@ -137,6 +137,7 @@ struct cppc_cpudata {
+ extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
+ extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
+ extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
++extern int cppc_set_enable(int cpu, u32 enable);
+ extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
+ extern bool acpi_cpc_valid(void);
+ extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
+@@ -157,6 +158,10 @@ static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
+ {
+ return -ENOTSUPP;
+ }
++static inline int cppc_set_enable(int cpu, u32 enable)
++{
++ return -ENOTSUPP;
++}
+ static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
+ {
+ return -ENOTSUPP;
diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c
-index c3b56db8b921..3f92ddadaad2 100644
+index c3b56db8b921..1443080868da 100644
--- a/tools/power/cpupower/lib/cpufreq.c
+++ b/tools/power/cpupower/lib/cpufreq.c
@@ -69,6 +69,14 @@ enum cpufreq_value {
@@ -1840,30 +1866,7 @@ index c3b56db8b921..3f92ddadaad2 100644
};
---
-2.33.0
-
-From c7249e524ce793bfe0575f45a0f8245f51b02af7 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sun, 20 Jun 2021 17:35:45 +0800
-Subject: [PATCH 16/19] 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.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- tools/power/cpupower/lib/cpufreq.c | 20 ++++++++++++++++++++
- tools/power/cpupower/lib/cpufreq.h | 3 +++
- tools/power/cpupower/utils/helpers/misc.c | 7 +++++++
- 3 files changed, 30 insertions(+)
-
-diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c
-index 3f92ddadaad2..37da87bdcfb1 100644
---- a/tools/power/cpupower/lib/cpufreq.c
-+++ b/tools/power/cpupower/lib/cpufreq.c
-@@ -790,3 +790,23 @@ unsigned long cpufreq_get_transitions(unsigned int cpu)
+@@ -774,3 +790,29 @@ unsigned long cpufreq_get_transitions(unsigned int cpu)
{
return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS);
}
@@ -1887,70 +1890,6 @@ index 3f92ddadaad2..37da87bdcfb1 100644
+
+ return cpuinfo_max == amd_pstate_max ? 1 : 0;
+}
-diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h
-index 95f4fd9e2656..d54d02a7a4f4 100644
---- a/tools/power/cpupower/lib/cpufreq.h
-+++ b/tools/power/cpupower/lib/cpufreq.h
-@@ -203,6 +203,9 @@ 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);
-+
- #ifdef __cplusplus
- }
- #endif
-diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
-index 07d80775fb68..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__)
-
- #include "cpupower_intern.h"
-+#include "cpufreq.h"
-
- #define MSR_AMD_HWCR 0xc0010015
-
-@@ -39,6 +40,12 @@ 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_INTEL_IDA)
- *support = *active = 1;
- return 0;
---
-2.33.0
-
-From cf79733de00a260c6d3e5038f00cdb91a71df9af Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Sun, 20 Jun 2021 18:25:55 +0800
-Subject: [PATCH 17/19] cpupower: add amd-pstate get data function to query the
- info
-
-Frequency-info needs an interface to query the current amd-pstate data.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- tools/power/cpupower/lib/cpufreq.c | 6 ++++++
- tools/power/cpupower/lib/cpufreq.h | 13 +++++++++++++
- 2 files changed, 19 insertions(+)
-
-diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c
-index 37da87bdcfb1..1443080868da 100644
---- a/tools/power/cpupower/lib/cpufreq.c
-+++ b/tools/power/cpupower/lib/cpufreq.c
-@@ -810,3 +810,9 @@ int amd_pstate_boost_enabled(unsigned int cpu)
-
- return cpuinfo_max == amd_pstate_max ? 1 : 0;
- }
+
+unsigned amd_pstate_get_data(unsigned int cpu, enum amd_pstate_param param)
+{
@@ -1958,13 +1897,16 @@ index 37da87bdcfb1..1443080868da 100644
+ param + AMD_PSTATE_HIGHEST_PERF);
+}
diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h
-index d54d02a7a4f4..954e72704fc0 100644
+index 95f4fd9e2656..954e72704fc0 100644
--- a/tools/power/cpupower/lib/cpufreq.h
+++ b/tools/power/cpupower/lib/cpufreq.h
-@@ -206,6 +206,19 @@ int cpufreq_set_frequency(unsigned int cpu,
- int amd_pstate_boost_support(unsigned int cpu);
- int amd_pstate_boost_enabled(unsigned int cpu);
+@@ -203,6 +203,22 @@ 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,
@@ -1981,23 +1923,6 @@ index d54d02a7a4f4..954e72704fc0 100644
#ifdef __cplusplus
}
#endif
---
-2.33.0
-
-From 573a0ff1add6bb6df585d6535abaaa0e1afc61c9 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Thu, 10 Jun 2021 23:48:03 +0800
-Subject: [PATCH 18/19] cpupower: print amd-pstate information on cpupower
-
-amd-pstate kernel module is using the fine grain frequency instead of
-acpi hardware pstate. So the performance and frequency values should be
-printed in frequency-info.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- tools/power/cpupower/utils/cpufreq-info.c | 27 ++++++++++++++++++++---
- 1 file changed, 24 insertions(+), 3 deletions(-)
-
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
index f9895e31ff5a..9eabed209adc 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
@@ -2036,419 +1961,106 @@ index f9895e31ff5a..9eabed209adc 100644
ret = decode_pstates(cpu, b_states, pstates, &pstate_no);
if (ret)
return ret;
---
-2.33.0
-
-From abfcbc164c1aa0c63d5e256854bad977a9645586 Mon Sep 17 00:00:00 2001
-From: Huang Rui <ray.huang@amd.com>
-Date: Thu, 10 Jun 2021 23:40:18 +0800
-Subject: [PATCH 19/19] Documentation: amd-pstate: add amd-pstate driver
- introduction
-
-Introduce the amd-pstate driver design and implementation.
-
-Signed-off-by: Huang Rui <ray.huang@amd.com>
----
- Documentation/admin-guide/pm/amd_pstate.rst | 377 ++++++++++++++++++
- .../admin-guide/pm/working-state.rst | 1 +
- 2 files changed, 378 insertions(+)
- create mode 100644 Documentation/admin-guide/pm/amd_pstate.rst
-
-diff --git a/Documentation/admin-guide/pm/amd_pstate.rst b/Documentation/admin-guide/pm/amd_pstate.rst
-new file mode 100644
-index 000000000000..c3659dde0cee
---- /dev/null
-+++ b/Documentation/admin-guide/pm/amd_pstate.rst
-@@ -0,0 +1,377 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+.. include:: <isonum.txt>
-+
-+===============================================
-+``amd-pstate`` CPU Performance Scaling Driver
-+===============================================
-+
-+:Copyright: |copy| 2021 Advanced Micro Devices, Inc.
-+
-+:Author: Huang Rui <ray.huang@amd.com>
-+
-+
-+Introduction
-+===================
-+
-+``amd-pstate`` is the AMD CPU performance scaling driver that introduces a
-+new CPU frequency control mechanism on modern AMD APU and CPU series in
-+Linux kernel. The new mechanism is based on Collaborative Processor
-+Performance Control (CPPC) which provides finer grain frequency management
-+than legacy ACPI hardware P-States. Current AMD CPU/APU platforms are using
-+the ACPI P-states driver to manage CPU frequency and clocks with switching
-+only in 3 P-states. CPPC replaces the ACPI P-states controls, allows a
-+flexible, low-latency interface for the Linux kernel to directly
-+communicate the performance hints to hardware.
-+
-+``amd-pstate`` leverages the Linux kernel governors such as ``schedutil``,
-+``ondemand``, etc. to manage the performance hints which are provided by
-+CPPC hardware functionality that internally follows the hardware
-+specification (for details refer to AMD64 Architecture Programmer's Manual
-+Volume 2: System Programming [1]_). Currently ``amd-pstate`` supports basic
-+frequency control function according to kernel governors on some of the
-+Zen2 and Zen3 processors, and we will implement more AMD specific functions
-+in future after we verify them on the hardware and SBIOS.
-+
-+
-+AMD CPPC Overview
-+=======================
-+
-+Collaborative Processor Performance Control (CPPC) interface enumerates a
-+continuous, abstract, and unit-less performance value in a scale that is
-+not tied to a specific performance state / frequency. This is an ACPI
-+standard [2]_ which software can specify application performance goals and
-+hints as a relative target to the infrastructure limits. AMD processors
-+provides the low latency register model (MSR) instead of AML code
-+interpreter for performance adjustments. ``amd-pstate`` will initialize a
-+``struct cpufreq_driver`` instance ``amd_pstate_driver`` with the callbacks
-+to manage each performance update behavior. ::
-+
-+ Highest Perf ------>+-----------------------+ +-----------------------+
-+ | | | |
-+ | | | |
-+ | | Max Perf ---->| |
-+ | | | |
-+ | | | |
-+ Nominal Perf ------>+-----------------------+ +-----------------------+
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | Desired Perf ---->| |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ | | | |
-+ Lowest non- | | | |
-+ linear perf ------>+-----------------------+ +-----------------------+
-+ | | | |
-+ | | Lowest perf ---->| |
-+ | | | |
-+ Lowest perf ------>+-----------------------+ +-----------------------+
-+ | | | |
-+ | | | |
-+ | | | |
-+ 0 ------>+-----------------------+ +-----------------------+
-+
-+ AMD P-States Performance Scale
-+
-+
-+.. _perf_cap:
-+
-+AMD CPPC Performance Capability
-+--------------------------------
-+
-+Highest Performance (RO)
-+.........................
-+
-+It is the absolute maximum performance an individual processor may reach,
-+assuming ideal conditions. This performance level may not be sustainable
-+for long durations and may only be achievable if other platform components
-+are in a specific state; for example, it may require other processors be in
-+an idle state. This would be equivalent to the highest frequencies
-+supported by the processor.
-+
-+Nominal (Guaranteed) Performance (RO)
-+......................................
-+
-+It is the maximum sustained performance level of the processor, assuming
-+ideal operating conditions. In absence of an external constraint (power,
-+thermal, etc.) this is the performance level the processor is expected to
-+be able to maintain continuously. All cores/processors are expected to be
-+able to sustain their nominal performance state simultaneously.
-+
-+Lowest non-linear Performance (RO)
-+...................................
-+
-+It is the lowest performance level at which nonlinear power savings are
-+achieved, for example, due to the combined effects of voltage and frequency
-+scaling. Above this threshold, lower performance levels should be generally
-+more energy efficient than higher performance levels. This register
-+effectively conveys the most efficient performance level to ``amd-pstate``.
-+
-+Lowest Performance (RO)
-+........................
-+
-+It is the absolute lowest performance level of the processor. Selecting a
-+performance level lower than the lowest nonlinear performance level may
-+cause an efficiency penalty but should reduce the instantaneous power
-+consumption of the processor.
-+
-+AMD CPPC Performance Control
-+------------------------------
-+
-+``amd-pstate`` passes performance goals through these registers. The
-+register drives the behavior of the desired performance target.
-+
-+Minimum requested performance (RW)
-+...................................
-+
-+``amd-pstate`` specifies the minimum allowed performance level.
-+
-+Maximum requested performance (RW)
-+...................................
-+
-+``amd-pstate`` specifies a limit the maximum performance that is expected
-+to be supplied by the hardware.
-+
-+Desired performance target (RW)
-+...................................
-+
-+``amd-pstate`` specifies a desired target in the CPPC performance scale as
-+a relative number. This can be expressed as percentage of nominal
-+performance (infrastructure max). Below the nominal sustained performance
-+level, desired performance expresses the average performance level of the
-+processor subject to hardware. Above the nominal performance level,
-+processor must provide at least nominal performance requested and go higher
-+if current operating conditions allow.
-+
-+Energy Performance Preference (EPP) (RW)
-+.........................................
-+
-+Provides a hint to the hardware if software wants to bias toward performance
-+(0x0) or energy efficiency (0xff).
-+
-+
-+Key Governors Support
-+=======================
-+
-+``amd-pstate`` can be used with all the (generic) scaling governors listed
-+by the ``scaling_available_governors`` policy attribute in ``sysfs``. Then,
-+it is responsible for the configuration of policy objects corresponding to
-+CPUs and provides the ``CPUFreq`` core (and the scaling governors attached
-+to the policy objects) with accurate information on the maximum and minimum
-+operating frequencies supported by the hardware. Users can check the
-+``scaling_cur_freq`` information comes from the ``CPUFreq`` core.
-+
-+``amd-pstate`` mainly supports ``schedutil`` and ``ondemand`` for dynamic
-+frequency control. It is to fine tune the processor configuration on
-+``amd-pstate`` to the ``schedutil`` with CPU CFS scheduler. ``amd-pstate``
-+registers adjust_perf callback to implement the CPPC similar performance
-+update behavior. It is initialized by ``sugov_start`` and then populate the
-+CPU's update_util_data pointer to assign ``sugov_update_single_perf`` as
-+the utilization update callback function in CPU scheduler. CPU scheduler
-+will call ``cpufreq_update_util`` and assign the target performance
-+according to the ``struct sugov_cpu`` that utilization update belongs to.
-+Then ``amd-pstate`` updates the desired performance according to the CPU
-+scheduler assigned.
-+
-+
-+Processor Support
-+=======================
-+
-+The ``amd-pstate`` initialization will fail if the _CPC in ACPI SBIOS is
-+not existed at the detected processor, and it uses ``acpi_cpc_valid`` to
-+check the _CPC existence. All Zen based processors support legacy ACPI
-+hardware P-States function, so while the ``amd-pstate`` fails to be
-+initialized, the kernel will fall back to initialize ``acpi-cpufreq``
-+driver.
-+
-+There are two types of hardware implementations for ``amd-pstate``: one is
-+`Full MSR Support <perf_cap_>`_ and another is `Shared Memory Support
-+<perf_cap_>`_. It can use :c:macro:`X86_FEATURE_AMD_CPPC_EXT` feature flag
-+(for details refer to Processor Programming Reference (PPR) for AMD Family
-+19h Model 21h, Revision B0 Processors [3]_) to indicate the different
-+types. ``amd-pstate`` is to register different ``amd_pstate_perf_funcs``
-+instances for different hardware implementations.
-+
-+Currently, some of Zen2 and Zen3 processors support ``amd-pstate``. In the
-+future, it will be supported on more and more AMD processors.
-+
-+Full MSR Support
-+-----------------
-+
-+Some new Zen3 processors such as Cezanne provide the MSR registers directly
-+while the :c:macro:`X86_FEATURE_AMD_CPPC_EXT` CPU feature flag is set.
-+``amd-pstate`` can handle the MSR register to implement the fast switch
-+function in ``CPUFreq`` that can shrink latency of frequency control on the
-+interrupt context.
-+
-+Shared Memory Support
-+----------------------
-+
-+If :c:macro:`X86_FEATURE_AMD_CPPC_EXT` CPU feature flag is not set, that
-+means the processor supports shared memory solution. In this case,
-+``amd-pstate`` uses the ``cppc_acpi`` helper methods to implement the
-+callback functions of ``amd_pstate_perf_funcs``.
-+
-+
-+AMD P-States and ACPI hardware P-States always can be supported in one
-+processor. But AMD P-States has the higher priority and if it is enabled
-+with :c:macro:`MSR_AMD_CPPC_ENABLE` or ``cppc_set_enable``, it will respond
-+to the request from AMD P-States.
-+
-+
-+User Space Interface in ``sysfs``
-+==================================
-+
-+``amd-pstate`` exposes several global attributes (files) in ``sysfs`` to
-+control its functionality at the system level. They located in the
-+``/sys/devices/system/cpu/cpufreq/policyX/`` directory and affect all CPUs. ::
-+
-+ root@hr-test1:/home/ray# ls /sys/devices/system/cpu/cpufreq/policy0/*amd*
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_highest_perf
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_freq
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_perf
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_perf
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_max_freq
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_min_freq
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_nominal_freq
-+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_nominal_perf
-+ /sys/devices/system/cpu/cpufreq/policy0/is_amd_pstate_enabled
-+
-+
-+``is_amd_pstate_enabled``
-+
-+Query whether current kernel loads ``amd-pstate`` to enable the AMD
-+P-States functionality.
-+This attribute is read-only.
-+
-+``amd_pstate_highest_perf / amd_pstate_max_freq``
-+
-+Maximum CPPC performance and CPU frequency that the driver is allowed to
-+set in percent of the maximum supported CPPC performance level (the highest
-+performance supported in `AMD CPPC Performance Capability <perf_cap_>`_).
-+This attribute is read-only.
-+
-+``amd_pstate_nominal_perf / amd_pstate_nominal_freq``
-+
-+Nominal CPPC performance and CPU frequency that the driver is allowed to
-+set in percent of the maximum supported CPPC performance level (Please see
-+nominal performance in `AMD CPPC Performance Capability <perf_cap_>`_).
-+This attribute is read-only.
-+
-+``amd_pstate_lowest_nonlinear_perf / amd_pstate_lowest_nonlinear_freq``
-+
-+The lowest non-linear CPPC performance and CPU frequency that the driver is
-+allowed to set in percent of the maximum supported CPPC performance level
-+(Please see the lowest non-linear performance in `AMD CPPC Performance
-+Capability <perf_cap_>`_).
-+This attribute is read-only.
-+
-+``amd_pstate_lowest_perf / amd_pstate_min_freq``
-+
-+The lowest physical CPPC performance and CPU frequency.
-+This attribute is read-only.
-+
-+
-+``amd-pstate`` vs ``acpi-cpufreq``
-+======================================
-+
-+On majority of AMD platforms supported by ``acpi-cpufreq``, the ACPI tables
-+provided by the platform firmware used for CPU performance scaling, but
-+only provides 3 P-states on AMD processors.
-+However, on modern AMD APU and CPU series, it provides the collaborative
-+processor performance control according to ACPI protocol and customize this
-+for AMD platforms. That is fine-grain and continuous frequency range
-+instead of the legacy hardware P-states. ``amd-pstate`` is the kernel
-+module which supports the new AMD P-States mechanism on most of future AMD
-+platforms. The AMD P-States mechanism will be the more performance and energy
-+efficiency frequency management method on AMD processors.
-+
-+``cpupower`` tool support for ``amd-pstate``
-+===============================================
-+
-+``amd-pstate`` is supported on ``cpupower`` tool that can be used to dump the frequency
-+information. And it is in progress to support more and more operations for new
-+``amd-pstate`` module with this tool. ::
-+
-+ root@hr-test1:/home/ray# cpupower frequency-info
-+ analyzing CPU 0:
-+ driver: amd-pstate
-+ CPUs which run at the same hardware frequency: 0
-+ CPUs which need to have their frequency coordinated by software: 0
-+ maximum transition latency: 131 us
-+ hardware limits: 400 MHz - 4.68 GHz
-+ available cpufreq governors: ondemand conservative powersave userspace performance schedutil
-+ current policy: frequency should be within 400 MHz and 4.68 GHz.
-+ The governor "schedutil" may decide which speed to use
-+ within this range.
-+ current CPU frequency: Unable to call hardware
-+ current CPU frequency: 4.02 GHz (asserted by call to kernel)
-+ boost state support:
-+ Supported: yes
-+ Active: yes
-+ AMD PSTATE Highest Performance: 166. Maximum Frequency: 4.68 GHz.
-+ AMD PSTATE Nominal Performance: 117. Nominal Frequency: 3.30 GHz.
-+ AMD PSTATE Lowest Non-linear Performance: 39. Lowest Non-linear Frequency: 1.10 GHz.
-+ AMD PSTATE Lowest Performance: 15. Lowest Frequency: 400 MHz.
-+
+diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
+index 72eb43593180..78218c54acca 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)
+ if (ext_cpuid_level >= 0x80000008 &&
+ cpuid_ebx(0x80000008) & (1 << 4))
+ cpu_info->caps |= CPUPOWER_CAP_AMD_RDPRU;
+
-+Diagnostics and Tuning
-+=======================
++ if (cpupower_amd_pstate_enabled(0)) {
++ cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE;
+
-+Trace Events
-+--------------
++ /*
++ * If AMD P-state is enabled, the firmware will treat
++ * AMD P-state function as high priority.
++ */
++ cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB;
++ cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB_MSR;
++ cpu_info->caps &= ~CPUPOWER_CAP_AMD_HW_PSTATE;
++ cpu_info->caps &= ~CPUPOWER_CAP_AMD_PSTATEDEF;
++ }
+ }
+
+ 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
+--- 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,
+ #define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100
+ #define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200
+ #define CPUPOWER_CAP_AMD_CPB_MSR 0x00000400
++#define CPUPOWER_CAP_AMD_PSTATE 0x00000800
+
+ #define CPUPOWER_AMD_CPBDIS 0x02000000
+
+@@ -135,6 +136,11 @@ 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);
+
-+There are two static trace events that can be used for ``amd-pstate``
-+diagnostics. One of them is the cpu_frequency trace event generally used
-+by ``CPUFreq``, and the other one is the ``amd_pstate_perf`` trace event
-+specific to ``amd-pstate``. The following sequence of shell commands can
-+be used to enable them and see their output (if the kernel is generally
-+configured to support event tracing). ::
++/* AMD PSTATE enabling **************************/
+
-+ root@hr-test1:/home/ray# cd /sys/kernel/tracing/
-+ root@hr-test1:/sys/kernel/tracing# echo 1 > events/amd_cpu/enable
-+ root@hr-test1:/sys/kernel/tracing# cat trace
-+ # tracer: nop
-+ #
-+ # entries-in-buffer/entries-written: 47827/42233061 #P:2
-+ #
-+ # _-----=> irqs-off
-+ # / _----=> need-resched
-+ # | / _---=> hardirq/softirq
-+ # || / _--=> preempt-depth
-+ # ||| / delay
-+ # TASK-PID CPU# |||| TIMESTAMP FUNCTION
-+ # | | | |||| | |
-+ <idle>-0 [000] d.s. 244057.464842: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
-+ <idle>-0 [000] d.h. 244057.475436: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
-+ <idle>-0 [000] d.h. 244057.476629: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
-+ <idle>-0 [000] d.s. 244057.484847: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
-+ <idle>-0 [000] d.h. 244057.499821: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
-+ avahi-daemon-528 [000] d... 244057.513568: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6
++extern unsigned long cpupower_amd_pstate_enabled(unsigned int cpu);
+
-+The cpu_frequency trace event will be triggered either by the ``schedutil`` scaling
-+governor (for the policies it is attached to), or by the ``CPUFreq`` core (for the
-+policies with other scaling governors).
+ /*
+ * 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__)
+
+ #include "cpupower_intern.h"
++#include "cpufreq.h"
+
+ #define MSR_AMD_HWCR 0xc0010015
+
+@@ -39,6 +40,12 @@ 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_INTEL_IDA)
+ *support = *active = 1;
+ return 0;
+@@ -83,6 +90,26 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val)
+ return 0;
+ }
+
++unsigned long cpupower_amd_pstate_enabled(unsigned int cpu)
++{
++ char linebuf[MAX_LINE_LEN];
++ char path[SYSFS_PATH_MAX];
++ unsigned long val;
++ char *endp;
+
-+Reference
-+===========
++ snprintf(path, sizeof(path),
++ PATH_TO_CPU "cpu%u/cpufreq/is_amd_pstate_enabled", cpu);
+
-+.. [1] AMD64 Architecture Programmer's Manual Volume 2: System Programming,
-+ https://www.amd.com/system/files/TechDocs/24593.pdf
++ if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0)
++ return 0;
+
-+.. [2] Advanced Configuration and Power Interface Specification,
-+ https://uefi.org/sites/default/files/resources/ACPI_Spec_6_4_Jan22.pdf
++ val = strtoul(linebuf, &endp, 0);
++ if (endp == linebuf || errno == ERANGE)
++ return 0;
+
-+.. [3] Processor Programming Reference (PPR) for AMD Family 19h Model 21h, Revision B0 Processors
-+ https://www.amd.com/system/files/TechDocs/55898_B1_pub_0.50.zip
++ return val;
++}
+
-diff --git a/Documentation/admin-guide/pm/working-state.rst b/Documentation/admin-guide/pm/working-state.rst
-index f40994c422dc..28db6156b55d 100644
---- a/Documentation/admin-guide/pm/working-state.rst
-+++ b/Documentation/admin-guide/pm/working-state.rst
-@@ -11,6 +11,7 @@ Working-State Power Management
- intel_idle
- cpufreq
- intel_pstate
-+ amd_pstate
- cpufreq_drivers
- intel_epb
- intel-speed-select
+ #endif /* #if defined(__i386__) || defined(__x86_64__) */
+
+ /* get_cpustate
--
2.33.0