summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authordragonn2021-10-02 18:39:30 +0200
committerdragonn2021-10-02 18:46:42 +0200
commit1a7d00bb70c5f03cf9ec04e6ab94ad47aa7be450 (patch)
treeb4a3f38d9177d6b3a7fb3ef91ad184a72c01a16c
parent3fd8f33c94d648c87abfb4db970367cf6b6633a6 (diff)
downloadaur-1a7d00bb70c5f03cf9ec04e6ab94ad47aa7be450.tar.gz
update fan curve patch, 5.14.9, update media patches, tablet mode
-rw-r--r--PKGBUILD29
-rw-r--r--sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch97
-rw-r--r--sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch38
-rw-r--r--sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-Allow-configuring-SW_TABLET.patch58
-rw-r--r--sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch13
-rw-r--r--sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch60
-rw-r--r--sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch548
-rw-r--r--sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch492
-rw-r--r--sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch892
-rw-r--r--sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch36
-rw-r--r--sys-kernel_arch-sources-g14_files-9010-amd-apci-allow-c3.patch34
11 files changed, 1327 insertions, 970 deletions
diff --git a/PKGBUILD b/PKGBUILD
index 7bf22aa1e6a0..6e986feed272 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,8 +1,8 @@
# Maintainer: Jan Alexander Steffens (heftig) <jan.steffens@gmail.com>
pkgbase=linux-g14
-pkgver=5.14.6.arch1
-pkgrel=1
+pkgver=5.14.9.arch1
+pkgrel=3
pkgdesc='Linux'
_srctag=v${pkgver%.*}-${pkgver##*.}
url="https://lab.retarded.farm/zappel/asus-rog-zephyrus-g14/"
@@ -39,7 +39,8 @@ source=(
"sys-kernel_arch-sources-g14_files-0044-claymore.patch"
"sys-kernel_arch-sources-g14_files-0045-v5-asus-wmi-Add-support-for-platform_profile.patch"
"sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch"
-
+ "sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch"
+ "sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch"
# k10temp support for Zen3 APUs
#"sys-kernel_arch-sources-g14_files-8001-x86-amd_nb-Add-AMD-family-19h-model-50h-PCI-ids.patch"
@@ -61,11 +62,12 @@ source=(
"sys-kernel_arch-sources-g14_files-8021-mt76-mt7921-fix-the-inconsistent-state-between-bind-and-unbind.patch"
"sys-kernel_arch-sources-g14_files-8022-mt76-mt7921-report-HE-MU-radiotap.patch"
"sys-kernel_arch-sources-g14_files-8023-v2-mt76-mt7921-fix-kernel-warning-from-cfg80211_calculate_bitrate.patch"
+ "sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch"
#"sys-kernel_arch-sources-g14_files-8024-mediatek-19-09-2021-squashed.patch"
# squashed s0ix enablement through 2021-09-03
- "sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch"
+ "sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch"
#"sys-kernel_arch-sources-g14_files-9002-amd-pmc-delay-test.patch"
# a small amd_pmc SMU debugging patch per Mario Limonciello @AMD
#"sys-kernel_arch-sources-g14_files-9002-amd-pmc-smu-register-dump-for-diagnostics.patch"
@@ -79,7 +81,7 @@ source=(
"sys-kernel_arch-sources-g14_files-9008-fix-cpu-hotplug.patch"
"sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch"
- #"sys-kernel_arch-sources-g14_files-9010-amd-apci-allow-c3.patch"
+ "sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch"
)
validpgpkeys=(
@@ -114,13 +116,15 @@ sha256sums=('SKIP'
'1770fec49335bc93194e9e55ced49e1cb67f2df4bf6948e80712a0b2ba50fa49'
'6da4010f86a74125969fd3dbc953da7b45209d33ff3d216474c3399e82e893ff'
'eb391b6d1ebf7ef99ece00b23609b94180a1f3c0149bcf05f6bbeb74d0b724c7'
- '526052481abf77ab25ae1b27567e459bb9d18bd4928ed904a1bc4bbd97833f0c'
+ 'e88c856444a306b06e82c90677ef797d09bef46957926d046c1cbb4218fb8f52'
+ '9f65f64addd66df45d90184ac4ea25c735ceb2dfff1d6d22c73d9f01a3be262a'
'544464bf0807b324120767d55867f03014a9fda4e1804768ca341be902d7ade4'
'f7a4bf6293912bfc4a20743e58a5a266be8c4dbe3c1862d196d3a3b45f2f7c90'
'ee8794a551e33226900654d5c806183bf3b9b2e06f64fdc322987215d233d399'
'2d854fc70297bb52bbc27dbf35ca019800530e40565be9740704d7f81bc4c763'
'1cec0be41732a23c709e66d4a67e71bc5a75c77a3e4b73faafb5d7bfd3fafc0f'
- 'e62cbe1cb1577b1d80095fbb566d0516592e6174e7740e61a340164aff9bf2ec')
+ '9025ca0788fbacea25200e6ac17036960000424843f544cdd781052231da7903'
+ 'e7bd53abc9fddc66790a2e63637b4e2b54ed541f41a2f0fb3aca91ea64ff90dc')
# notable microarch levels:
#
@@ -218,6 +222,14 @@ prepare() {
make -s kernelrelease > version
echo "Prepared $pkgbase version $(<version)"
+
+ scripts/config --enable CONFIG_CMDLINE_BOOL \
+ --set-str CONFIG_CMDLINE "pm_debug_messages amd_pmc.dyndbg=+p acpi.dyndbg=file drivers/acpi/x86/s2idle.c +p" \
+ --disable CMDLINE_OVERRIDE
+
+ scripts/config --enable CONFIG_PINCTRL_AMD
+ scripts/config --module CONFIG_X86_AMD_PSTATE
+ scripts/config --module CONFIG_AMD_PMC
}
build() {
@@ -230,7 +242,7 @@ _package() {
depends=(coreutils kmod initramfs)
optdepends=('crda: to set the correct wireless channels of your country'
'linux-firmware: firmware images needed for some devices')
- provides=(VIRTUALBOX-GUEST-MODULES WIREGUARD-MODULE)
+ provides=(VIRTUALBOX-GUEST-MODULES WIREGUARD-MODULE linux-rog)
replaces=(virtualbox-guest-modules-arch wireguard-arch)
cd $_srcname
@@ -254,6 +266,7 @@ _package() {
_package-headers() {
pkgdesc="Headers and scripts for building modules for the $pkgdesc kernel"
+ provides=(linux-rog linux-rog-headers)
depends=(pahole)
cd $_srcname
diff --git a/sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch b/sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch
index ce6665e3db5d..be11606fad13 100644
--- a/sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch
+++ b/sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch
@@ -1,7 +1,7 @@
-From cfd3291fa2a77bf1029646da5945d83d1021609a Mon Sep 17 00:00:00 2001
+From b9e2eae999333fc1ad9ddf4cf0e36a0eaee239e2 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
Date: Sun, 29 Aug 2021 13:21:23 +1200
-Subject: [PATCH v14 1/1] asus-wmi: Add support for custom fan curves
+Subject: [PATCH v15] asus-wmi: Add support for custom fan curves
Add support for custom fan curves found on some ASUS ROG laptops.
@@ -28,12 +28,12 @@ Notes:
Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
- drivers/platform/x86/asus-wmi.c | 611 ++++++++++++++++++++-
+ drivers/platform/x86/asus-wmi.c | 608 ++++++++++++++++++++-
include/linux/platform_data/x86/asus-wmi.h | 2 +
- 2 files changed, 605 insertions(+), 8 deletions(-)
+ 2 files changed, 602 insertions(+), 8 deletions(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index e14fb5fa7324..7569f34bac3e 100644
+index e14fb5fa7324..8b0ed1969d86 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -106,8 +106,17 @@ module_param(fnlock_default, bool, 0444);
@@ -64,27 +64,20 @@ index e14fb5fa7324..7569f34bac3e 100644
u32 arg5;
} __packed;
-@@ -173,6 +183,19 @@ enum fan_type {
+@@ -173,6 +183,12 @@ enum fan_type {
FAN_TYPE_SPEC83, /* starting in Spec 8.3, use CPU_FAN_CTRL */
};
-+/*
-+ * The related ACPI method for testing availability also returns the factory
-+ * default fan curves. We save them here so that a user can reset custom
-+ * settings if required.
-+ */
+struct fan_curve_data {
+ bool enabled;
+ u8 temps[FAN_CURVE_POINTS];
+ u8 percents[FAN_CURVE_POINTS];
-+ u8 default_temps[FAN_CURVE_POINTS];
-+ u8 default_percents[FAN_CURVE_POINTS];
+};
+
struct asus_wmi {
int dsts_id;
int spec;
-@@ -220,6 +243,10 @@ struct asus_wmi {
+@@ -220,6 +236,10 @@ struct asus_wmi {
bool throttle_thermal_policy_available;
u8 throttle_thermal_policy_mode;
@@ -95,7 +88,7 @@ index e14fb5fa7324..7569f34bac3e 100644
struct platform_profile_handler platform_profile_handler;
bool platform_profile_support;
-@@ -285,6 +312,103 @@ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
+@@ -285,6 +305,103 @@ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
}
EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method);
@@ -199,7 +192,7 @@ index e14fb5fa7324..7569f34bac3e 100644
static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
{
struct acpi_buffer input;
-@@ -1806,6 +1930,13 @@ static ssize_t pwm1_enable_store(struct device *dev,
+@@ -1806,6 +1923,13 @@ static ssize_t pwm1_enable_store(struct device *dev,
}
asus->fan_pwm_mode = state;
@@ -213,7 +206,7 @@ index e14fb5fa7324..7569f34bac3e 100644
return count;
}
-@@ -1953,9 +2084,9 @@ static int fan_boost_mode_check_present(struct asus_wmi *asus)
+@@ -1953,9 +2077,9 @@ static int fan_boost_mode_check_present(struct asus_wmi *asus)
static int fan_boost_mode_write(struct asus_wmi *asus)
{
@@ -225,7 +218,7 @@ index e14fb5fa7324..7569f34bac3e 100644
value = asus->fan_boost_mode;
-@@ -2013,10 +2144,10 @@ static ssize_t fan_boost_mode_store(struct device *dev,
+@@ -2013,10 +2137,10 @@ static ssize_t fan_boost_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -238,11 +231,11 @@ index e14fb5fa7324..7569f34bac3e 100644
result = kstrtou8(buf, 10, &new_mode);
if (result < 0) {
-@@ -2043,6 +2174,458 @@ static ssize_t fan_boost_mode_store(struct device *dev,
+@@ -2043,6 +2167,462 @@ static ssize_t fan_boost_mode_store(struct device *dev,
// Fan boost mode: 0 - normal, 1 - overboost, 2 - silent
static DEVICE_ATTR_RW(fan_boost_mode);
-+/* Custom fan curves per-profile **********************************************/
++/* Custom fan curves *********************************************************/
+
+static void fan_curve_copy_from_buf(struct fan_curve_data *data, u8 *buf)
+{
@@ -250,14 +243,11 @@ index e14fb5fa7324..7569f34bac3e 100644
+
+ for (i = 0; i < FAN_CURVE_POINTS; i++) {
+ data->temps[i] = buf[i];
-+ data->default_temps[i] = buf[i];
+ }
+
+ for (i = 0; i < FAN_CURVE_POINTS; i++) {
+ data->percents[i] =
+ 255 * buf[i + FAN_CURVE_POINTS] / 100;
-+ data->default_percents[i] =
-+ 255 * buf[i + FAN_CURVE_POINTS] / 100;
+ }
+}
+
@@ -291,9 +281,7 @@ index e14fb5fa7324..7569f34bac3e 100644
+ return 0;
+}
+
-+/*
-+ * Check if capability exists, and populate defaults.
-+ */
++/* Check if capability exists, and populate defaults */
+static int fan_curve_check_present(struct asus_wmi *asus, bool *available,
+ u32 fan_dev)
+{
@@ -312,27 +300,35 @@ index e14fb5fa7324..7569f34bac3e 100644
+ return 0;
+}
+
-+static struct fan_curve_data *fan_curve_data_select(struct asus_wmi *asus,
++/* Determine which fan the attribute is for if SENSOR_ATTR */
++static struct fan_curve_data *fan_curve_attr_select(struct asus_wmi *asus,
++ struct device_attribute *attr)
++{
++ int index = to_sensor_dev_attr(attr)->index;
++
++ return &asus->custom_fan_curves[index & FAN_CURVE_DEV_GPU];
++}
++
++/* Determine which fan the attribute is for if SENSOR_ATTR_2 */
++static struct fan_curve_data *fan_curve_attr_2_select(struct asus_wmi *asus,
+ struct device_attribute *attr)
+{
-+ /* Determine which fan the attribute is for */
+ int nr = to_sensor_dev_attr_2(attr)->nr;
-+ int fan = nr & FAN_CURVE_DEV_GPU;
+
-+ return &asus->custom_fan_curves[fan];
++ return &asus->custom_fan_curves[nr & FAN_CURVE_DEV_GPU];
+}
+
+static ssize_t fan_curve_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
++ struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr);
+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+ /* Determine if temperature or pwm */
-+ int nr = to_sensor_dev_attr_2(attr)->nr;
+ struct fan_curve_data *data;
-+ int value, index;
++ int value, index, nr;
+
-+ data = fan_curve_data_select(asus, attr);
-+ index = to_sensor_dev_attr_2(attr)->index;
++ data = fan_curve_attr_2_select(asus, attr);
++ index = dev_attr->index;
++ nr = dev_attr->nr;
+
+ if (nr & FAN_CURVE_PWM_MASK)
+ value = data->percents[index];
@@ -348,7 +344,7 @@ index e14fb5fa7324..7569f34bac3e 100644
+static int fan_curve_write(struct asus_wmi *asus,
+ struct device_attribute *attr, u32 fan_dev)
+{
-+ struct fan_curve_data *data = fan_curve_data_select(asus, attr);
++ struct fan_curve_data *data = fan_curve_attr_2_select(asus, attr);
+ u32 arg1 = 0, arg2 = 0, arg3 = 0, arg4 = 0;
+ u8 *percents = data->percents;
+ u8 *temps = data->temps;
@@ -395,16 +391,16 @@ index e14fb5fa7324..7569f34bac3e 100644
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
++ struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr);
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ struct fan_curve_data *data;
+ u8 value;
+ int err;
+
-+ int index = to_sensor_dev_attr_2(attr)->index;
-+ int nr = to_sensor_dev_attr_2(attr)->nr;
-+ int pwm = nr & FAN_CURVE_PWM_MASK;
++ int pwm = dev_attr->nr & FAN_CURVE_PWM_MASK;
++ int index = dev_attr->index;
+
-+ data = fan_curve_data_select(asus, attr);
++ data = fan_curve_attr_2_select(asus, attr);
+
+ err = kstrtou8(buf, 10, &value);
+ if (err < 0)
@@ -430,9 +426,11 @@ index e14fb5fa7324..7569f34bac3e 100644
+ struct device_attribute *attr, char *buf)
+{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+ struct fan_curve_data *data = fan_curve_data_select(asus, attr);
++ struct fan_curve_data *data;
+ int out = 2;
+
++ data = fan_curve_attr_select(asus, attr);
++
+ if (data->enabled)
+ out = 1;
+
@@ -461,10 +459,9 @@ index e14fb5fa7324..7569f34bac3e 100644
+{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ struct fan_curve_data *data;
-+ int value;
-+ int err;
++ int value, err;
+
-+ data = fan_curve_data_select(asus, attr);
++ data = fan_curve_attr_select(asus, attr);
+
+ err = kstrtoint(buf, 10, &value);
+ if (err < 0)
@@ -697,7 +694,7 @@ index e14fb5fa7324..7569f34bac3e 100644
/* Throttle thermal policy ****************************************************/
static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
-@@ -2053,8 +2636,8 @@ static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
+@@ -2053,8 +2633,8 @@ static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
asus->throttle_thermal_policy_available = false;
err = asus_wmi_get_devstate(asus,
@@ -708,7 +705,7 @@ index e14fb5fa7324..7569f34bac3e 100644
if (err) {
if (err == -ENODEV)
return 0;
-@@ -2092,6 +2675,12 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus)
+@@ -2092,6 +2672,12 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus)
return -EIO;
}
@@ -721,7 +718,7 @@ index e14fb5fa7324..7569f34bac3e 100644
return 0;
}
-@@ -2901,7 +3490,7 @@ static int show_call(struct seq_file *m, void *data)
+@@ -2901,7 +3487,7 @@ static int show_call(struct seq_file *m, void *data)
if (ACPI_FAILURE(status))
return -EIO;
@@ -730,7 +727,7 @@ index e14fb5fa7324..7569f34bac3e 100644
if (obj && obj->type == ACPI_TYPE_INTEGER)
seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id,
asus->debug.dev_id, asus->debug.ctrl_param,
-@@ -3035,6 +3624,10 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -3035,6 +3621,10 @@ static int asus_wmi_add(struct platform_device *pdev)
if (err)
goto fail_hwmon;
@@ -741,7 +738,7 @@ index e14fb5fa7324..7569f34bac3e 100644
err = asus_wmi_led_init(asus);
if (err)
goto fail_leds;
-@@ -3106,6 +3699,7 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -3106,6 +3696,7 @@ static int asus_wmi_add(struct platform_device *pdev)
asus_wmi_sysfs_exit(asus->platform_device);
fail_sysfs:
fail_throttle_thermal_policy:
@@ -749,7 +746,7 @@ index e14fb5fa7324..7569f34bac3e 100644
fail_platform_profile_setup:
if (asus->platform_profile_support)
platform_profile_remove();
-@@ -3131,6 +3725,7 @@ static int asus_wmi_remove(struct platform_device *device)
+@@ -3131,6 +3722,7 @@ static int asus_wmi_remove(struct platform_device *device)
asus_wmi_debugfs_exit(asus);
asus_wmi_sysfs_exit(asus->platform_device);
asus_fan_set_auto(asus);
diff --git a/sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch b/sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch
new file mode 100644
index 000000000000..50b23b3fd618
--- /dev/null
+++ b/sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch
@@ -0,0 +1,38 @@
+From fc6c2cf30dbddc4ec365febd78e2138abf1353f8 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 12 Aug 2021 16:28:23 +0200
+Subject: [PATCH 2/2] platform/x86: asus-nb-wmi: Add tablet_mode_sw=lid-flip
+ quirk for the TP200s
+
+The Asus TP200s / E205SA 360 degree hinges 2-in-1 supports reporting
+SW_TABLET_MODE info through the ASUS_WMI_DEVID_LID_FLIP WMI device-id.
+Add a quirk to enable this.
+
+BugLink: https://gitlab.freedesktop.org/libinput/libinput/-/issues/639
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index 9929eedf7dd8..a81dc4b191b7 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -462,6 +462,15 @@ static const struct dmi_system_id asus_quirks[] = {
+ },
+ .driver_data = &quirk_asus_use_lid_flip_devid,
+ },
++ {
++ .callback = dmi_matched,
++ .ident = "ASUS TP200s / E205SA",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "E205SA"),
++ },
++ .driver_data = &quirk_asus_use_lid_flip_devid,
++ },
+ {},
+ };
+
+--
+2.31.1
diff --git a/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-Allow-configuring-SW_TABLET.patch b/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-Allow-configuring-SW_TABLET.patch
new file mode 100644
index 000000000000..d497fb6171be
--- /dev/null
+++ b/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-Allow-configuring-SW_TABLET.patch
@@ -0,0 +1,58 @@
+From 0c2f287ea670acbf9d4ed68efd55b5f2b76b50ca Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 28 Jul 2021 20:35:15 +0200
+Subject: [PATCH 1/2] platform/x86: asus-nb-wmi: Allow configuring
+ SW_TABLET_MODE method with a module option
+
+Unfortunately we have been unable to find a reliable way to detect if
+and how SW_TABLET_MODE reporting is supported, so we are relying on
+DMI quirks for this.
+
+Add a module-option to specify the SW_TABLET_MODE method so that this can
+be easily tested without needing to rebuild the kernel.
+
+BugLink: https://gitlab.freedesktop.org/libinput/libinput/-/issues/639
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/platform/x86/asus-nb-wmi.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index 0cb927f0f301..9929eedf7dd8 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -41,6 +41,10 @@ static int wapf = -1;
+ module_param(wapf, uint, 0444);
+ MODULE_PARM_DESC(wapf, "WAPF value");
+
++static int tablet_mode_sw = -1;
++module_param(tablet_mode_sw, uint, 0444);
++MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip");
++
+ static struct quirk_entry *quirks;
+
+ static bool asus_q500a_i8042_filter(unsigned char data, unsigned char str,
+@@ -477,6 +481,21 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
+ else
+ wapf = quirks->wapf;
+
++ switch (tablet_mode_sw) {
++ case 0:
++ quirks->use_kbd_dock_devid = false;
++ quirks->use_lid_flip_devid = false;
++ break;
++ case 1:
++ quirks->use_kbd_dock_devid = true;
++ quirks->use_lid_flip_devid = false;
++ break;
++ case 2:
++ quirks->use_kbd_dock_devid = false;
++ quirks->use_lid_flip_devid = true;
++ break;
++ }
++
+ if (quirks->i8042_filter) {
+ ret = i8042_install_filter(quirks->i8042_filter);
+ if (ret) {
+--
+2.31.1
diff --git a/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch b/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch
new file mode 100644
index 000000000000..6327dc76407f
--- /dev/null
+++ b/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch
@@ -0,0 +1,13 @@
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index f24e002ca703..f85fec0e1b76 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -42,7 +42,7 @@ module_param(wapf, uint, 0444);
+ MODULE_PARM_DESC(wapf, "WAPF value");
+
+ static int tablet_mode_sw = -1;
+-module_param(tablet_mode_sw, uint, 0444);
++module_param(tablet_mode_sw, int, 0444);
+ MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip");
+
+ static struct quirk_entry *quirks; \ No newline at end of file
diff --git a/sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch b/sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch
new file mode 100644
index 000000000000..b6011f06913f
--- /dev/null
+++ b/sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch
@@ -0,0 +1,60 @@
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index a9855a2dd561..b71dbb2c9f5e 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -411,6 +411,9 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK},
+
+ /* Additional MediaTek MT7921 Bluetooth devices */
++ { USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK |
++ BTUSB_WIDEBAND_SPEECH |
++ BTUSB_VALID_LE_STATES },
+ { USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index b71dbb2c9f5e..e2a6f0c99e3f 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -417,6 +417,9 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
++ { USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK |
++ BTUSB_WIDEBAND_SPEECH |
++ BTUSB_VALID_LE_STATES },
+
+ /* Additional Realtek 8723AE Bluetooth devices */
+ { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
+
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 1e5cac6f071b..7b69a97bd0e9 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -422,6 +422,9 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x13d3, 0x3563), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
++ { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
++ BTUSB_WIDEBAND_SPEECH |
++ BTUSB_VALID_LE_STATES },
+
+ /* Additional Realtek 8723AE Bluetooth devices */
+ { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 66c8f3cdc0c0..cd961d5977d3 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -410,6 +410,9 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x13d3, 0x3563), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
++ { USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK |
++ BTUSB_WIDEBAND_SPEECH |
++ BTUSB_VALID_LE_STATES },
+ { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
diff --git a/sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch b/sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch
index 012fe05076f2..e69de29bb2d1 100644
--- a/sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch
+++ b/sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch
@@ -1,548 +0,0 @@
-From c76d0e81f0480e7a40db872677e837ae4c8a44aa Mon Sep 17 00:00:00 2001
-From: Scott B <arglebargle@arglebargle.dev>
-Date: Sat, 18 Sep 2021 15:36:27 -0700
-Subject: [PATCH] v5.14.6 s0ix patch 2021-09-18
-
-Squashed commit of the following:
-
-commit 90f4fc1b714d70c368ae7458b5c9682775a6e0e1
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Thu Sep 16 18:11:30 2021 +0530
-
- platform/x86: amd-pmc: Check s0i3 cycle status
-
- As the PM firmware returns the status of the last s0i3 in the smu_metrics
- structure, the existing name "s0i3_cyclecount" seems to be a misnomer.
- Change it accordingly to "s0i3_last_entry_status".
-
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
- Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
-
-commit 014e2fdeaf232d1c5fd1a74813f749a7a6c0f812
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Thu Sep 16 18:10:02 2021 +0530
-
- platform/x86: amd-pmc: Export Idlemask values based on the APU
-
- IdleMask is the metric used by the PM firmware to know the status of each
- of the Hardware IP blocks monitored by the PM firmware.
-
- Knowing this value is key to get the information of s2idle suspend/resume
- status. This value is mapped to PMC scratch registers, retrieve them
- accordingly based on the CPU family and the underlying firmware support.
-
- Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
- Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 50913ca2c9ffb1d07fe0f402249ae151e95e87df
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Wed Sep 15 16:52:16 2021 -0500
-
- ACPI: processor idle: Allow playing dead in C3
-
- commit 1a022e3f1be1 ("idle, x86: Allow off-lined CPU to enter
- deeper C states") originally allowed offlined CPUs to play dead
- up to ACPI C2. Although this improves power consumption of offlined
- CPUs, it does not allow the CPUs to get into the deepest state
- on AMD platforms blocking s0i3 entry.
-
- BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1708
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 949ccde94b90a5966c23d1bd286b28778b5dbf20
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Thu Sep 9 11:19:43 2021 -0500
-
- platform/x86: amd-pmc: Increase the response register timeout
-
- There have been reports of approximately a 9% failure rate in SMU
- communication timeouts with s0i3 entry on some OEM designs. Currently
- the design in amd-pmc is to try every 100us for up to 20ms.
-
- However the GPU driver which also communicates with the SMU using a
- mailbox register which the driver polls every 1us for up to 2000ms.
- In the GPU driver this was increased by commit 055162645a40 ("drm/amd/pm:
- increase time out value when sending msg to SMU")
-
- Increase the maximum timeout used by amd-pmc to 2000ms to match this
- behavior.
-
- Cc: stable@kernel.org
- Reported-by: Julian Sikorski <belegdol@gmail.com>
- BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1629
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 235b6c0ae71da1245e4cb5fcede464f629d8d1ec
-Author: Scott B <28817345+foundObjects@users.noreply.github.com>
-Date: Wed Jul 21 18:10:28 2021 -0700
-
- DEBUG: amd-pmc smu register dump for diagnostics
-
- patch this per Mario's request:
- https://gitlab.freedesktop.org/drm/amd/-/issues/1629#note_1000332
-
-commit fe0d159834023ad729170befd9cd09f82cef4471
-Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
-Date: Tue Aug 31 17:36:12 2021 +0530
-
- pinctrl: amd: Add irq field data
-
- pinctrl_amd use gpiochip_get_data() to get their local state containers
- back from the gpiochip passed as amd_gpio chip data.
-
- Hence added irq field data to get directly using amd_gpio chip data.
-
- Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
-
-commit 9cf6e041f865e42514bcb8429a20c1c056d7a5ab
-Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
-Date: Tue Aug 31 17:36:13 2021 +0530
-
- pinctrl: amd: Handle wake-up interrupt
-
- Enable/disable power management wakeup mode, which is disabled by
- default. enable_irq_wake enables wakes the system from sleep.
-
- Hence added enable/disable irq_wake to handle wake-up interrupt.
-
- Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
-
-commit 91f7908d258f1edc3287429b236710ee790dd217
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Tue Aug 31 11:36:19 2021 -0500
-
- ACPI: PM: s2idle: Run both AMD and Microsoft methods if both are supported
-
- It was reported that on "HP ENVY x360" that power LED does not come back
- on, certain keys like brightness controls do not work, and the fan never
- spins up, even under load.
-
- In analysis of the SSDT it's clear that the Microsoft UUID doesn't provide
- functional support, but rather the AMD UUID should be supporting this
- system.
-
- Because this is a gap in the expected logic, confirmation with internal
- team is that AMD uPEP *does* run even when Microsoft UUID present, but
- most OEM systems have adopted value of "0x3" for supported functions and
- hence nothing runs.
-
- Henceforth add support for running both Microsoft and AMD methods. This
- approach will also allow the same logic on Intel systems if desired at a
- future time as well by pulling the evaluation of
- `lps0_dsm_func_mask_microsoft` out of the if block for
- `acpi_s2idle_vendor_amd`.
-
- BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1691
- Reported-by: Maxwell Beck <max@ryt.one>
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 04cd8a215540e78dba7c63aeba71fc563ea4038b
-Author: Scott B <28817345+foundObjects@users.noreply.github.com>
-Date: Tue Jul 20 23:33:01 2021 -0700
-
- drm/amd/pm: Add information about SMU12 firmware version
-
- hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066835.html
-
- This information is useful for root causing issues with S0ix.
-
- Signed-off-by: Mario Limonciello <mario.limonciello at amd.com>
-
-commit dd4c25dc971802f3f8ccb9d21f3b4842b8894c5e
-Author: Scott B <28817345+foundObjects@users.noreply.github.com>
-Date: Tue Jul 20 23:31:31 2021 -0700
-
- drm/amd/pm: Add information about SMU11 firmware version
-
- hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066834.html
-
- This information is useful for root causing issues with S0ix.
-
- Signed-off-by: Mario Limonciello <mario.limonciello at amd.com>
----
- drivers/acpi/processor_idle.c | 3 +-
- drivers/acpi/x86/s2idle.c | 67 ++++++++-------
- .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 3 +
- .../gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c | 3 +
- drivers/pinctrl/pinctrl-amd.c | 19 +++--
- drivers/pinctrl/pinctrl-amd.h | 1 +
- drivers/platform/x86/amd-pmc.c | 84 ++++++++++++++++++-
- 7 files changed, 143 insertions(+), 37 deletions(-)
-
-diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
-index 095c8aca141e..1b6529396371 100644
---- a/drivers/acpi/processor_idle.c
-+++ b/drivers/acpi/processor_idle.c
-@@ -789,7 +789,8 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
- state->enter = acpi_idle_enter;
-
- state->flags = 0;
-- if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) {
-+ if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2
-+ || cx->type == ACPI_STATE_C3) {
- state->enter_dead = acpi_idle_play_dead;
- drv->safe_state_index = count;
- }
-diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
-index 3a308461246a..7d1976e5dd8b 100644
---- a/drivers/acpi/x86/s2idle.c
-+++ b/drivers/acpi/x86/s2idle.c
-@@ -449,25 +449,30 @@ int acpi_s2idle_prepare_late(void)
- if (pm_debug_messages_on)
- lpi_check_constraints();
-
-- if (lps0_dsm_func_mask_microsoft > 0) {
-+ /* screen off */
-+ if (lps0_dsm_func_mask > 0)
-+ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-+ ACPI_LPS0_SCREEN_OFF_AMD :
-+ ACPI_LPS0_SCREEN_OFF,
-+ lps0_dsm_func_mask, lps0_dsm_guid);
-+
-+ if (lps0_dsm_func_mask_microsoft > 0)
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-+
-+ /* lps0 entry */
-+ if (lps0_dsm_func_mask > 0)
-+ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-+ ACPI_LPS0_ENTRY_AMD :
-+ ACPI_LPS0_ENTRY,
-+ lps0_dsm_func_mask, lps0_dsm_guid);
-+ if (lps0_dsm_func_mask_microsoft > 0) {
-+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
-+ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-+ /* modern standby entry */
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
-- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-- } else if (acpi_s2idle_vendor_amd()) {
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-- } else {
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
-- lps0_dsm_func_mask, lps0_dsm_guid);
- }
--
- return 0;
- }
-
-@@ -476,24 +481,30 @@ void acpi_s2idle_restore_early(void)
- if (!lps0_device_handle || sleep_no_lps0)
- return;
-
-- if (lps0_dsm_func_mask_microsoft > 0) {
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
-- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-+ /* mdoern standby exit */
-+ if (lps0_dsm_func_mask_microsoft > 0)
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-+
-+ /* lps0 exit */
-+ if (lps0_dsm_func_mask > 0)
-+ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-+ ACPI_LPS0_EXIT_AMD :
-+ ACPI_LPS0_EXIT,
-+ lps0_dsm_func_mask, lps0_dsm_guid);
-+ if (lps0_dsm_func_mask_microsoft > 0)
-+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
-+ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-+
-+ /* screen on */
-+ if (lps0_dsm_func_mask_microsoft > 0)
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-- } else if (acpi_s2idle_vendor_amd()) {
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-- } else {
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
-- lps0_dsm_func_mask, lps0_dsm_guid);
-- }
-+ if (lps0_dsm_func_mask > 0)
-+ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-+ ACPI_LPS0_SCREEN_ON_AMD :
-+ ACPI_LPS0_SCREEN_ON,
-+ lps0_dsm_func_mask, lps0_dsm_guid);
- }
-
- static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
-diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
-index 0a5d46ac9ccd..626d7c2bdf66 100644
---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
-+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
-@@ -272,6 +272,9 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
- break;
- }
-
-+ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n",
-+ smu_version, smu_major, smu_minor, smu_debug);
-+
- /*
- * 1. if_version mismatch is not critical as our fw is designed
- * to be backward compatible.
-diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
-index d60b8c5e8715..00ebc381a605 100644
---- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
-+++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
-@@ -88,6 +88,9 @@ int smu_v12_0_check_fw_version(struct smu_context *smu)
- if (smu->is_apu)
- adev->pm.fw_version = smu_version;
-
-+ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n",
-+ smu_version, smu_major, smu_minor, smu_debug);
-+
- /*
- * 1. if_version mismatch is not critical as our fw is designed
- * to be backward compatible.
-diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
-index 5b764740b829..d19974aceb2e 100644
---- a/drivers/pinctrl/pinctrl-amd.c
-+++ b/drivers/pinctrl/pinctrl-amd.c
-@@ -445,6 +445,7 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- u32 wake_mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3);
-+ int err;
-
- raw_spin_lock_irqsave(&gpio_dev->lock, flags);
- pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
-@@ -457,6 +458,15 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
- writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
- raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
-
-+ if (on)
-+ err = enable_irq_wake(gpio_dev->irq);
-+ else
-+ err = disable_irq_wake(gpio_dev->irq);
-+
-+ if (err)
-+ dev_err(&gpio_dev->pdev->dev, "failed to %s wake-up interrupt\n",
-+ on ? "enable" : "disable");
-+
- return 0;
- }
-
-@@ -904,7 +914,6 @@ static struct pinctrl_desc amd_pinctrl_desc = {
- static int amd_gpio_probe(struct platform_device *pdev)
- {
- int ret = 0;
-- int irq_base;
- struct resource *res;
- struct amd_gpio *gpio_dev;
- struct gpio_irq_chip *girq;
-@@ -927,9 +936,9 @@ static int amd_gpio_probe(struct platform_device *pdev)
- if (!gpio_dev->base)
- return -ENOMEM;
-
-- irq_base = platform_get_irq(pdev, 0);
-- if (irq_base < 0)
-- return irq_base;
-+ gpio_dev->irq = platform_get_irq(pdev, 0);
-+ if (gpio_dev->irq < 0)
-+ return gpio_dev->irq;
-
- #ifdef CONFIG_PM_SLEEP
- gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins,
-@@ -989,7 +998,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
- goto out2;
- }
-
-- ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler,
-+ ret = devm_request_irq(&pdev->dev, gpio_dev->irq, amd_gpio_irq_handler,
- IRQF_SHARED, KBUILD_MODNAME, gpio_dev);
- if (ret)
- goto out2;
-diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h
-index 95e763424042..1d4317073654 100644
---- a/drivers/pinctrl/pinctrl-amd.h
-+++ b/drivers/pinctrl/pinctrl-amd.h
-@@ -98,6 +98,7 @@ struct amd_gpio {
- struct resource *res;
- struct platform_device *pdev;
- u32 *saved_regs;
-+ int irq;
- };
-
- /* KERNCZ configuration*/
-diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
-index 3481479a2942..a489f1e4d7dc 100644
---- a/drivers/platform/x86/amd-pmc.c
-+++ b/drivers/platform/x86/amd-pmc.c
-@@ -29,6 +29,10 @@
- #define AMD_PMC_REGISTER_RESPONSE 0x980
- #define AMD_PMC_REGISTER_ARGUMENT 0x9BC
-
-+/* PMC Scratch Registers */
-+#define AMD_PMC_SCRATCH_REG_CZN 0x94
-+#define AMD_PMC_SCRATCH_REG_YC 0xD14
-+
- /* Base address of SMU for mapping physical address to virtual address */
- #define AMD_PMC_SMU_INDEX_ADDRESS 0xB8
- #define AMD_PMC_SMU_INDEX_DATA 0xBC
-@@ -71,7 +75,7 @@
- #define AMD_CPU_ID_YC 0x14B5
-
- #define PMC_MSG_DELAY_MIN_US 100
--#define RESPONSE_REGISTER_LOOP_MAX 200
-+#define RESPONSE_REGISTER_LOOP_MAX 20000
-
- #define SOC_SUBSYSTEM_IP_MAX 12
- #define DELAY_MIN_US 2000
-@@ -110,6 +114,10 @@ struct amd_pmc_dev {
- u32 base_addr;
- u32 cpu_id;
- u32 active_ips;
-+/* SMU version information */
-+ u16 major;
-+ u16 minor;
-+ u16 rev;
- struct device *dev;
- struct mutex lock; /* generic mutex lock */
- #if IS_ENABLED(CONFIG_DEBUG_FS)
-@@ -133,7 +141,7 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
- struct smu_metrics {
- u32 table_version;
- u32 hint_count;
-- u32 s0i3_cyclecount;
-+ u32 s0i3_last_entry_status;
- u32 timein_s0i2;
- u64 timeentering_s0i3_lastcapture;
- u64 timeentering_s0i3_totaltime;
-@@ -162,7 +170,8 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
- seq_puts(s, "\n=== SMU Statistics ===\n");
- seq_printf(s, "Table Version: %d\n", table.table_version);
- seq_printf(s, "Hint Count: %d\n", table.hint_count);
-- seq_printf(s, "S0i3 Cycle Count: %d\n", table.s0i3_cyclecount);
-+ seq_printf(s, "Last S0i3 Status: %s\n", table.s0i3_last_entry_status ? "Success" :
-+ "Unknown/Fail");
- seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture);
- seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture);
-
-@@ -201,6 +210,66 @@ static int s0ix_stats_show(struct seq_file *s, void *unused)
- }
- DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
-
-+static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
-+{
-+ int rc;
-+ u32 val;
-+
-+ rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, 1);
-+ if (rc)
-+ return rc;
-+
-+ dev->major = (val >> 16) & GENMASK(15, 0);
-+ dev->minor = (val >> 8) & GENMASK(7, 0);
-+ dev->rev = (val >> 0) & GENMASK(7, 0);
-+
-+ dev_dbg(dev->dev, "SMU version is %u.%u.%u\n", dev->major, dev->minor, dev->rev);
-+
-+ return 0;
-+}
-+
-+static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
-+ struct seq_file *s)
-+{
-+ u32 val;
-+
-+ switch (pdev->cpu_id) {
-+ case AMD_CPU_ID_CZN:
-+ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN);
-+ break;
-+ case AMD_CPU_ID_YC:
-+ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (dev)
-+ dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val);
-+
-+ if (s)
-+ seq_printf(s, "SMU idlemask : 0x%x\n", val);
-+
-+ return 0;
-+}
-+
-+static int amd_pmc_idlemask_show(struct seq_file *s, void *unused)
-+{
-+ struct amd_pmc_dev *dev = s->private;
-+ int rc;
-+
-+ if (dev->major > 56 || (dev->major >= 55 && dev->minor >= 37)) {
-+ rc = amd_pmc_idlemask_read(dev, NULL, s);
-+ if (rc)
-+ return rc;
-+ } else {
-+ seq_puts(s, "Unsupported SMU version for Idlemask\n");
-+ }
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(amd_pmc_idlemask);
-+
- static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
- {
- debugfs_remove_recursive(dev->dbgfs_dir);
-@@ -213,6 +282,8 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
- &smu_fw_info_fops);
- debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev,
- &s0ix_stats_fops);
-+ debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev,
-+ &amd_pmc_idlemask_fops);
- }
- #else
- static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
-@@ -270,6 +341,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg
- u32 val;
-
- mutex_lock(&dev->lock);
-+ amd_pmc_dump_registers(dev);
- /* Wait until we get a valid response */
- rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
- val, val != 0, PMC_MSG_DELAY_MIN_US,
-@@ -349,6 +421,8 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev)
- amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_RESET, 0);
- amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_START, 0);
-
-+ /* Dump the IdleMask before we send hint to SMU */
-+ amd_pmc_idlemask_read(pdev, dev, NULL);
- msg = amd_pmc_get_os_hint(pdev);
- rc = amd_pmc_send_cmd(pdev, 1, NULL, msg, 0);
- if (rc)
-@@ -371,6 +445,9 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
- if (rc)
- dev_err(pdev->dev, "resume failed\n");
-
-+ /* Dump the IdleMask to see the blockers */
-+ amd_pmc_idlemask_read(pdev, dev, NULL);
-+
- return 0;
- }
-
-@@ -457,6 +534,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
- if (err)
- dev_err(dev->dev, "SMU debugging info not supported on this platform\n");
-
-+ amd_pmc_get_smu_version(dev);
- platform_set_drvdata(pdev, dev);
- amd_pmc_dbgfs_register(dev);
- return 0;
---
-2.33.0
-
diff --git a/sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch b/sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch
new file mode 100644
index 000000000000..b623f875f138
--- /dev/null
+++ b/sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch
@@ -0,0 +1,492 @@
+From 6b1881a52169644ae314fa082a2c4daa152c46b3 Mon Sep 17 00:00:00 2001
+From: Scott B <arglebargle@arglebargle.dev>
+Date: Fri, 1 Oct 2021 08:26:54 -0700
+Subject: [PATCH] v5.14.9 s0ix patch 2021-10-01
+
+Squashed commit of the following:
+
+commit 9d22c6f69dce036dab2a4d17911bc2ce84df9537
+Author: Lijo Lazar <lijo.lazar@amd.com>
+Date: Fri Oct 1 18:16:25 2021 +0800
+
+ drm/amdgpu: During s0ix don't wait to signal GFXOFF
+
+ In the rare event when GFX IP suspend coincides with a s0ix entry, don't
+ schedule a delayed work, instead signal PMFW immediately to allow GFXOFF
+ entry. GFXOFF is a prerequisite for s0ix entry. PMFW needs to be
+ signaled about GFXOFF status before amd-pmc module passes OS HINT
+ to PMFW telling that everything is ready for a safe s0ix entry.
+
+ Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1712
+
+ Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
+ Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+ Reviewed-by: Mario Limonciello <mario.limonciell@amd.com>
+
+commit 0c5d3b01b4d999992439ca9f749e202cc0cc8578
+Author: Sanket Goswami <Sanket.Goswami@amd.com>
+Date: Tue Sep 21 17:30:20 2021 +0530
+
+ platform/x86: amd-pmc: Add a message to print resume time info
+
+ Add a message to print the resume time information obtained from the
+ smu_metrics structure.
+
+ Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
+
+commit bae72b8e72aac7590d2677830926d960e72edade
+Author: Sanket Goswami <Sanket.Goswami@amd.com>
+Date: Tue Sep 21 17:29:10 2021 +0530
+
+ platform/x86: amd-pmc: Send command to dump data after clearing OS_HINT
+
+ It was reported that the resume stats received from the firmware are
+ always zero. This happens because the SMU expects the driver to send the
+ command to dump the log data after clearing the OS_HINT.
+
+ Adjust the order of the commands sent to SMU.
+
+ Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
+
+commit 6e5d6b64bff6e2a863cae9b22c5f5a8f7f7462ff
+Author: Sanket Goswami <Sanket.Goswami@amd.com>
+Date: Thu Sep 16 18:11:30 2021 +0530
+
+ platform/x86: amd-pmc: Check s0i3 cycle status
+
+ As the PM firmware returns the status of the last s0i3 in the smu_metrics
+ structure, the existing name "s0i3_cyclecount" seems to be a misnomer.
+ Change it accordingly to "s0i3_last_entry_status".
+
+ Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
+ Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+
+commit fdf1b62b3ad1a54a041ebf49ba9b081deb8a6634
+Author: Sanket Goswami <Sanket.Goswami@amd.com>
+Date: Thu Sep 16 18:10:02 2021 +0530
+
+ platform/x86: amd-pmc: Export Idlemask values based on the APU
+
+ IdleMask is the metric used by the PM firmware to know the status of each
+ of the Hardware IP blocks monitored by the PM firmware.
+
+ Knowing this value is key to get the information of s2idle suspend/resume
+ status. This value is mapped to PMC scratch registers, retrieve them
+ accordingly based on the CPU family and the underlying firmware support.
+
+ Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
+ Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 994c36c63556c54eaa3f02ea8b7e5b28fc1836cf
+Author: Mario Limonciello <mario.limonciello@amd.com>
+Date: Wed Sep 15 16:52:16 2021 -0500
+
+ ACPI: processor idle: Allow playing dead in C3
+
+ commit 1a022e3f1be1 ("idle, x86: Allow off-lined CPU to enter
+ deeper C states") originally allowed offlined CPUs to play dead
+ up to ACPI C2. Although this improves power consumption of offlined
+ CPUs, it does not allow the CPUs to get into the deepest state
+ on AMD platforms blocking s0i3 entry.
+
+ BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1708
+ Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+
+commit ffa37ed37e917dfa225598dcef8a86324784a4ff
+Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Date: Tue Aug 31 17:36:12 2021 +0530
+
+ pinctrl: amd: Add irq field data
+
+ pinctrl_amd use gpiochip_get_data() to get their local state containers
+ back from the gpiochip passed as amd_gpio chip data.
+
+ Hence added irq field data to get directly using amd_gpio chip data.
+
+ Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+commit b6c769a9687c626c8e068215035975b57fe954e8
+Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Date: Tue Aug 31 17:36:13 2021 +0530
+
+ pinctrl: amd: Handle wake-up interrupt
+
+ Enable/disable power management wakeup mode, which is disabled by
+ default. enable_irq_wake enables wakes the system from sleep.
+
+ Hence added enable/disable irq_wake to handle wake-up interrupt.
+
+ Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+commit 1fef466dd8e750ea6c86803277226cfee04df5d5
+Author: Scott B <28817345+foundObjects@users.noreply.github.com>
+Date: Wed Jul 21 18:10:28 2021 -0700
+
+ DEBUG: amd-pmc smu register dump for diagnostics
+
+ patch this per Mario's request:
+ https://gitlab.freedesktop.org/drm/amd/-/issues/1629#note_1000332
+
+commit 497175cc42db2ec66a9c17687c15eb8c45644c2c
+Author: Scott B <28817345+foundObjects@users.noreply.github.com>
+Date: Tue Jul 20 23:33:01 2021 -0700
+
+ drm/amd/pm: Add information about SMU12 firmware version
+
+ hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066835.html
+
+ This information is useful for root causing issues with S0ix.
+
+ Signed-off-by: Mario Limonciello <mario.limonciello at amd.com>
+
+commit 07447fae7c12ba3d9c014cfbb69ebda8fe0b4239
+Author: Scott B <28817345+foundObjects@users.noreply.github.com>
+Date: Tue Jul 20 23:31:31 2021 -0700
+
+ drm/amd/pm: Add information about SMU11 firmware version
+
+ hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066834.html
+
+ This information is useful for root causing issues with S0ix.
+
+ Signed-off-by: Mario Limonciello <mario.limonciello at amd.com>
+---
+ drivers/acpi/processor_idle.c | 3 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 14 ++-
+ .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 3 +
+ .../gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c | 3 +
+ drivers/pinctrl/pinctrl-amd.c | 19 ++--
+ drivers/pinctrl/pinctrl-amd.h | 1 +
+ drivers/platform/x86/amd-pmc.c | 90 +++++++++++++++++--
+ 7 files changed, 120 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index 095c8aca141e..1b6529396371 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -789,7 +789,8 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
+ state->enter = acpi_idle_enter;
+
+ state->flags = 0;
+- if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) {
++ if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2
++ || cx->type == ACPI_STATE_C3) {
+ state->enter_dead = acpi_idle_play_dead;
+ drv->safe_state_index = count;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+index b4ced45301be..1795d448c700 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+@@ -31,6 +31,8 @@
+ /* delay 0.1 second to enable gfx off feature */
+ #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100)
+
++#define GFX_OFF_NO_DELAY 0
++
+ /*
+ * GPU GFX IP block helpers function.
+ */
+@@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev)
+
+ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
+ {
++ unsigned long delay = GFX_OFF_DELAY_ENABLE;
++
+ if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
+ return;
+
+@@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
+
+ adev->gfx.gfx_off_req_count--;
+
+- if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state)
+- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
++ if (adev->gfx.gfx_off_req_count == 0 &&
++ !adev->gfx.gfx_off_state) {
++ /* If going to s2idle, no need to wait */
++ if (adev->in_s0ix)
++ delay = GFX_OFF_NO_DELAY;
++ schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
++ delay);
++ }
+ } else {
+ if (adev->gfx.gfx_off_req_count == 0) {
+ cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+index 0a5d46ac9ccd..626d7c2bdf66 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+@@ -272,6 +272,9 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
+ break;
+ }
+
++ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n",
++ smu_version, smu_major, smu_minor, smu_debug);
++
+ /*
+ * 1. if_version mismatch is not critical as our fw is designed
+ * to be backward compatible.
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
+index d60b8c5e8715..00ebc381a605 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
+@@ -88,6 +88,9 @@ int smu_v12_0_check_fw_version(struct smu_context *smu)
+ if (smu->is_apu)
+ adev->pm.fw_version = smu_version;
+
++ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n",
++ smu_version, smu_major, smu_minor, smu_debug);
++
+ /*
+ * 1. if_version mismatch is not critical as our fw is designed
+ * to be backward compatible.
+diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
+index 5b764740b829..d19974aceb2e 100644
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -445,6 +445,7 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+ u32 wake_mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3);
++ int err;
+
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+ pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
+@@ -457,6 +458,15 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+ writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+
++ if (on)
++ err = enable_irq_wake(gpio_dev->irq);
++ else
++ err = disable_irq_wake(gpio_dev->irq);
++
++ if (err)
++ dev_err(&gpio_dev->pdev->dev, "failed to %s wake-up interrupt\n",
++ on ? "enable" : "disable");
++
+ return 0;
+ }
+
+@@ -904,7 +914,6 @@ static struct pinctrl_desc amd_pinctrl_desc = {
+ static int amd_gpio_probe(struct platform_device *pdev)
+ {
+ int ret = 0;
+- int irq_base;
+ struct resource *res;
+ struct amd_gpio *gpio_dev;
+ struct gpio_irq_chip *girq;
+@@ -927,9 +936,9 @@ static int amd_gpio_probe(struct platform_device *pdev)
+ if (!gpio_dev->base)
+ return -ENOMEM;
+
+- irq_base = platform_get_irq(pdev, 0);
+- if (irq_base < 0)
+- return irq_base;
++ gpio_dev->irq = platform_get_irq(pdev, 0);
++ if (gpio_dev->irq < 0)
++ return gpio_dev->irq;
+
+ #ifdef CONFIG_PM_SLEEP
+ gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins,
+@@ -989,7 +998,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
+ goto out2;
+ }
+
+- ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler,
++ ret = devm_request_irq(&pdev->dev, gpio_dev->irq, amd_gpio_irq_handler,
+ IRQF_SHARED, KBUILD_MODNAME, gpio_dev);
+ if (ret)
+ goto out2;
+diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h
+index 95e763424042..1d4317073654 100644
+--- a/drivers/pinctrl/pinctrl-amd.h
++++ b/drivers/pinctrl/pinctrl-amd.h
+@@ -98,6 +98,7 @@ struct amd_gpio {
+ struct resource *res;
+ struct platform_device *pdev;
+ u32 *saved_regs;
++ int irq;
+ };
+
+ /* KERNCZ configuration*/
+diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
+index d6a7c896ac86..81b000241648 100644
+--- a/drivers/platform/x86/amd-pmc.c
++++ b/drivers/platform/x86/amd-pmc.c
+@@ -29,6 +29,10 @@
+ #define AMD_PMC_REGISTER_RESPONSE 0x980
+ #define AMD_PMC_REGISTER_ARGUMENT 0x9BC
+
++/* PMC Scratch Registers */
++#define AMD_PMC_SCRATCH_REG_CZN 0x94
++#define AMD_PMC_SCRATCH_REG_YC 0xD14
++
+ /* Base address of SMU for mapping physical address to virtual address */
+ #define AMD_PMC_SMU_INDEX_ADDRESS 0xB8
+ #define AMD_PMC_SMU_INDEX_DATA 0xBC
+@@ -110,6 +114,10 @@ struct amd_pmc_dev {
+ u32 base_addr;
+ u32 cpu_id;
+ u32 active_ips;
++/* SMU version information */
++ u16 major;
++ u16 minor;
++ u16 rev;
+ struct device *dev;
+ struct mutex lock; /* generic mutex lock */
+ #if IS_ENABLED(CONFIG_DEBUG_FS)
+@@ -133,7 +141,7 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
+ struct smu_metrics {
+ u32 table_version;
+ u32 hint_count;
+- u32 s0i3_cyclecount;
++ u32 s0i3_last_entry_status;
+ u32 timein_s0i2;
+ u64 timeentering_s0i3_lastcapture;
+ u64 timeentering_s0i3_totaltime;
+@@ -162,9 +170,12 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
+ seq_puts(s, "\n=== SMU Statistics ===\n");
+ seq_printf(s, "Table Version: %d\n", table.table_version);
+ seq_printf(s, "Hint Count: %d\n", table.hint_count);
+- seq_printf(s, "S0i3 Cycle Count: %d\n", table.s0i3_cyclecount);
++ seq_printf(s, "Last S0i3 Status: %s\n", table.s0i3_last_entry_status ? "Success" :
++ "Unknown/Fail");
+ seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture);
+ seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture);
++ seq_printf(s, "Time (in us) to resume from S0i3: %lld\n",
++ table.timeto_resume_to_os_lastcapture);
+
+ seq_puts(s, "\n=== Active time (in us) ===\n");
+ for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) {
+@@ -201,6 +212,66 @@ static int s0ix_stats_show(struct seq_file *s, void *unused)
+ }
+ DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
+
++static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
++{
++ int rc;
++ u32 val;
++
++ rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, 1);
++ if (rc)
++ return rc;
++
++ dev->major = (val >> 16) & GENMASK(15, 0);
++ dev->minor = (val >> 8) & GENMASK(7, 0);
++ dev->rev = (val >> 0) & GENMASK(7, 0);
++
++ dev_dbg(dev->dev, "SMU version is %u.%u.%u\n", dev->major, dev->minor, dev->rev);
++
++ return 0;
++}
++
++static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
++ struct seq_file *s)
++{
++ u32 val;
++
++ switch (pdev->cpu_id) {
++ case AMD_CPU_ID_CZN:
++ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN);
++ break;
++ case AMD_CPU_ID_YC:
++ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC);
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (dev)
++ dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val);
++
++ if (s)
++ seq_printf(s, "SMU idlemask : 0x%x\n", val);
++
++ return 0;
++}
++
++static int amd_pmc_idlemask_show(struct seq_file *s, void *unused)
++{
++ struct amd_pmc_dev *dev = s->private;
++ int rc;
++
++ if (dev->major > 56 || (dev->major >= 55 && dev->minor >= 37)) {
++ rc = amd_pmc_idlemask_read(dev, NULL, s);
++ if (rc)
++ return rc;
++ } else {
++ seq_puts(s, "Unsupported SMU version for Idlemask\n");
++ }
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(amd_pmc_idlemask);
++
+ static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
+ {
+ debugfs_remove_recursive(dev->dbgfs_dir);
+@@ -213,6 +284,8 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
+ &smu_fw_info_fops);
+ debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev,
+ &s0ix_stats_fops);
++ debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev,
++ &amd_pmc_idlemask_fops);
+ }
+ #else
+ static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
+@@ -270,6 +343,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg
+ u32 val;
+
+ mutex_lock(&dev->lock);
++ amd_pmc_dump_registers(dev);
+ /* Wait until we get a valid response */
+ rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
+ val, val != 0, PMC_MSG_DELAY_MIN_US,
+@@ -349,6 +423,8 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev)
+ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_RESET, 0);
+ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_START, 0);
+
++ /* Dump the IdleMask before we send hint to SMU */
++ amd_pmc_idlemask_read(pdev, dev, NULL);
+ msg = amd_pmc_get_os_hint(pdev);
+ rc = amd_pmc_send_cmd(pdev, 1, NULL, msg, 0);
+ if (rc)
+@@ -363,14 +439,17 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
+ int rc;
+ u8 msg;
+
+- /* Let SMU know that we are looking for stats */
+- amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
+-
+ msg = amd_pmc_get_os_hint(pdev);
+ rc = amd_pmc_send_cmd(pdev, 0, NULL, msg, 0);
+ if (rc)
+ dev_err(pdev->dev, "resume failed\n");
+
++ /* Let SMU know that we are looking for stats */
++ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
++
++ /* Dump the IdleMask to see the blockers */
++ amd_pmc_idlemask_read(pdev, dev, NULL);
++
+ return 0;
+ }
+
+@@ -457,6 +536,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
+ if (err)
+ dev_err(dev->dev, "SMU debugging info not supported on this platform\n");
+
++ amd_pmc_get_smu_version(dev);
+ platform_set_drvdata(pdev, dev);
+ amd_pmc_dbgfs_register(dev);
+ return 0;
+--
+2.33.0
+
diff --git a/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch b/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch
index 09471946e6f9..da19351fa6a8 100644
--- a/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch
+++ b/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch
@@ -1,11 +1,11 @@
-From 1cf7e7f39c0c1a259ffd8c58b69edfc933936913 Mon Sep 17 00:00:00 2001
+From e0aeb1b7aaf55f3550cac74057c0d850c6a8f24e Mon Sep 17 00:00:00 2001
From: Scott B <arglebargle@arglebargle.dev>
-Date: Thu, 9 Sep 2021 18:02:09 -0700
-Subject: [PATCH] amd-pstate v1
+Date: Sun, 26 Sep 2021 11:02:58 -0700
+Subject: [PATCH] amd-pstate v2
Squashed commit of the following:
-commit aee7d6c2aa9fde5120b03083676ad86bf293aeaa
+commit 15a541d4c1406bad735799bc0d663ac8c8ed860f
Author: Huang Rui <ray.huang@amd.com>
Date: Thu Jun 10 23:40:18 2021 +0800
@@ -15,7 +15,7 @@ Date: Thu Jun 10 23:40:18 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit d5130811e36f5557e2678de2f612c2db00a5c719
+commit 556f332dc97bf90e2df72482fd1d078bd9206ab4
Author: Huang Rui <ray.huang@amd.com>
Date: Thu Jun 10 23:48:03 2021 +0800
@@ -27,61 +27,95 @@ Date: Thu Jun 10 23:48:03 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 8c239cb8a6e3704a75ab4139fd275a7e17b336c6
+commit 8f775fa6057be3964ecdfe0616b15ac515dafc97
Author: Huang Rui <ray.huang@amd.com>
-Date: Sun Jun 20 18:25:55 2021 +0800
+Date: Sun Sep 26 16:26:06 2021 +0800
- cpupower: add amd-pstate get data function to query the info
+ cpupower: move print_speed function into misc helper
- Frequency-info needs an interface to query the current amd-pstate data.
+ The print_speed can be as a common function, and expose it into misc
+ helper header. Then it can be used on other helper files as well.
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit ce0b684f184fee1fba6b6e0ef4ae4506a0d275c1
+commit ecd25fc5e7776669011b06ec0142c42224e415fd
Author: Huang Rui <ray.huang@amd.com>
Date: Sun Jun 20 17:35:45 2021 +0800
cpupower: enable boost state support for amd-pstate module
- The AMD P-state boost API is different from ACPI hardware P-states, so
- implement the support for amd-pstate kernel module.
+ The legacy ACPI hardware P-States function has 3 P-States on ACPI table,
+ the CPU frequency only can be switched between the 3 P-States. While the
+ processor supports the boost state, it will have another boost state
+ that the frequency can be higher than P0 state, and the state can be
+ decoded by the function of decode_pstates() and read by
+ amd_pci_get_num_boost_states().
+
+ However, the new AMD P-States function is different than legacy ACPI
+ hardware P-State on AMD processors. That has a finer grain frequency
+ range between the highest and lowest frequency. And boost frequency is
+ actually the frequency which is mapped on highest performance ratio. The
+ similiar previous P0 frequency is mapped on nominal performance ratio.
+ If the highest performance on the processor is higher than nominal
+ performance, then we think the current processor supports the boost
+ state. And it uses amd_pstate_boost_init() to initialize boost for AMD
+ P-States function.
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 97f78342eb9bcecfe44ef5307941dea1051e3a75
+commit bdbc7ab476c821eadefa00b89e80f33439749bf6
Author: Huang Rui <ray.huang@amd.com>
Date: Sun Jun 20 17:07:25 2021 +0800
- cpupower: add amd-pstate sysfs entries into libcpufreq
+ cpupower: add amd-pstate sysfs definition and access helper
- These amd-pstate sysfs entries will be used on cpupower for amd-pstate
- kernel module.
+ Introduce the marco definitions and access helper function for
+ amd-pstate sysfs interfaces such as each performance goals and frequency
+ levels in amd helper file. They will be used to read the sysfs attribute
+ from amd-pstate cpufreq driver for cpupower utilities.
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit d99ecc31f798a4025baaea72607246dadedefca0
+commit e8d0f2a79d9ea76c838bc253389c3642139ebf05
+Author: Huang Rui <ray.huang@amd.com>
+Date: Sun Sep 26 10:55:53 2021 +0800
+
+ cpupower: add the function to get the sysfs value from specific table
+
+ Expose the helper into cpufreq header, then cpufreq driver can use this
+ function to get the sysfs value if it has any specific sysfs interfaces.
+
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit c084ef5a4583083d09812801fcc4f881b6b80102
Author: Huang Rui <ray.huang@amd.com>
Date: Sun Jun 27 22:40:14 2021 +0800
cpupower: initial AMD P-state capability
- If kernel enables AMD P-state, cpupower won't need to respond ACPI
- hardware P-states function anymore.
+ If kernel starts the amd-pstate module, the cpupower will initial the
+ capability flag as CPUPOWER_CAP_AMD_PSTATE. And once amd-pstate
+ capability is set, it won't need to set legacy ACPI relative
+ capabilities anymore.
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit f766224ca2c54192b9e9abaa50ce58ef5e72670d
+commit f531c849130c1104ad81232bcd03ab6e17f2661d
Author: Huang Rui <ray.huang@amd.com>
Date: Sun Jun 27 22:25:39 2021 +0800
cpupower: add the function to check amd-pstate enabled
- Introduce the cpupower_amd_pstate_enabled() to check whether the kernel
- mode enables amd-pstate.
+ The processor with amd-pstate function also supports legacy ACPI
+ hardware P-States feature as well. Once driver sets amd-pstate eanbled,
+ the processor will respond the finer grain amd-pstate feature instead of
+ legacy ACPI P-States. So it introduces the cpupower_amd_pstate_enabled()
+ to check whether the current kernel enables amd-pstate or acpi-cpufreq
+ module.
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 0eca00885d7ce1cf7c03b8999fce887c9bafc411
+commit 510b487ccfe71ab5c19e2d0ef624f8925f15f600
Author: Huang Rui <ray.huang@amd.com>
Date: Mon Jun 14 22:52:01 2021 +0800
@@ -92,7 +126,7 @@ Date: Mon Jun 14 22:52:01 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 9a70d7b125cad2356910cbf04e476d53b458c786
+commit 4351bf1becc53385a8ea76ddef076a753062309b
Author: Huang Rui <ray.huang@amd.com>
Date: Sun Jun 20 15:01:08 2021 +0800
@@ -103,7 +137,7 @@ Date: Sun Jun 20 15:01:08 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 48c5ae9172d62b6a6a8220f27afeaf47408ebb66
+commit 264932a7ddbee32b36af09261cc921e67bcdc61d
Author: Huang Rui <ray.huang@amd.com>
Date: Sun Jun 20 13:26:01 2021 +0800
@@ -114,7 +148,7 @@ Date: Sun Jun 20 13:26:01 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 4d003338827eca88097f35fae6e3ec75566bc788
+commit 40fde676994657f0c27cffb192d43f52e8da1c3d
Author: Huang Rui <ray.huang@amd.com>
Date: Sat Jun 19 23:41:30 2021 +0800
@@ -125,7 +159,7 @@ Date: Sat Jun 19 23:41:30 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit e8aa42d8143a5c8b65a63de34cd38bdc6d70fd82
+commit 690f2eaa700abee63d31c17873deac058433125b
Author: Huang Rui <ray.huang@amd.com>
Date: Thu Jun 10 23:13:00 2021 +0800
@@ -136,7 +170,7 @@ Date: Thu Jun 10 23:13:00 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 1cb45daf02f2cad44457ccc237c9d74f60eec621
+commit c9876ed4e1b126300ae8eecb2c3db64b2d043f88
Author: Huang Rui <ray.huang@amd.com>
Date: Thu Jun 10 20:24:00 2021 +0800
@@ -147,7 +181,7 @@ Date: Thu Jun 10 20:24:00 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 152251e4cc636f4748d308ac31089ae7fd4e09c9
+commit 668359efad049de2efaedffa4a94a029f6a24982
Author: Huang Rui <ray.huang@amd.com>
Date: Mon Aug 9 19:06:51 2021 +0800
@@ -159,7 +193,7 @@ Date: Mon Aug 9 19:06:51 2021 +0800
Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit a2a9f14e19c4b34986e6410dd4f430449a32d2a3
+commit 735f6c6664e3da48e67b44a6a59f9fa4b82c576d
Author: Huang Rui <ray.huang@amd.com>
Date: Fri Aug 13 18:43:47 2021 +0800
@@ -171,7 +205,7 @@ Date: Fri Aug 13 18:43:47 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit ffb5347387a6a070554d2e6f6af918ffbf1965c4
+commit ecab8f33c0660e9c96c42a5c27078a324185d601
Author: Huang Rui <ray.huang@amd.com>
Date: Thu Jun 10 18:04:45 2021 +0800
@@ -287,18 +321,39 @@ Date: Thu Jun 10 18:04:45 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 5648469cb7cd30bc5bbd460b362c09223bdec3e5
+commit 47c390a1770904355262aef37bc25f0cee3cc3fc
Author: Jinzhou Su <Jinzhou.Su@amd.com>
Date: Mon Aug 9 19:04:17 2021 +0800
ACPI: CPPC: add cppc enable register function
- Export the cppc enable register function for future use.
+ Add a new function to enable CPPC feature. This function
+ will write Continuous Performance Control package
+ EnableRegister field on the processor.
Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit a0f215fdf3e24f2a74aa767cb5faef008ca3881e
+commit 3b19018de66c74ed41fa6b9241fa5cffbbade6b2
+Author: Mario Limonciello <mario.limonciello@amd.com>
+Date: Wed Jul 28 05:48:34 2021 +0800
+
+ ACPI: CPPC: Check online CPUs for determining _CPC is valid
+
+ As this is a static check, it should be based upon what is currently
+ present on the system. This makes probeing more deterministic.
+
+ While local APIC flags field (lapic_flags) of cpu core in MADT table is
+ 0, then the cpu core won't be enabled. In this case, _CPC won't be found
+ in this core, and return back to _CPC invalid with walking through
+ possible cpus (include disable cpus). This is not expected, so switch to
+ check online CPUs instead.
+
+ Reported-by: Jinzhou Su <Jinzhou.Su@amd.com>
+ Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+ Signed-off-by: Huang Rui <ray.huang@amd.com>
+
+commit 2ab6419bfa88161ec5cf0ff45681923c793d9eff
Author: Huang Rui <ray.huang@amd.com>
Date: Mon Jan 25 15:50:24 2021 +0800
@@ -310,35 +365,42 @@ Date: Mon Jan 25 15:50:24 2021 +0800
Signed-off-by: Huang Rui <ray.huang@amd.com>
-commit 1bff64e92f53c19784369a0cc1b7a05c918ed941
+commit 1993446c3c798df5946f0717122f545dd8f1278d
Author: Huang Rui <ray.huang@amd.com>
Date: Thu Jan 28 10:50:26 2021 +0800
- x86/cpufreatures: add AMD CPPC extension feature flag
+ x86/cpufreatures: add AMD Collaborative Processor Performance Control feature flag
+
+ Add Collaborative Processor Performance Control feature flag for AMD
+ processors.
- Add Collaborative Processor Performance Control Extension feature flag
- for AMD processors.
+ This feature flag will be used on the following amd-pstate driver. The
+ amd-pstate driver has two approaches to implement the frequency control
+ behavior. That depends on the CPU hardware implementation. One is "Full
+ MSR Support" and another is "Shared Memory Support". The feature flag
+ indicates the current processors with "Full MSR Support".
Signed-off-by: Huang Rui <ray.huang@amd.com>
---
- Documentation/admin-guide/pm/amd_pstate.rst | 377 ++++++++
+ Documentation/admin-guide/pm/amd_pstate.rst | 377 +++++++++
.../admin-guide/pm/working-state.rst | 1 +
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/msr-index.h | 17 +
- drivers/acpi/cppc_acpi.c | 42 +
+ drivers/acpi/cppc_acpi.c | 50 +-
drivers/cpufreq/Kconfig.x86 | 13 +
drivers/cpufreq/Makefile | 5 +
drivers/cpufreq/amd-pstate-trace.c | 2 +
drivers/cpufreq/amd-pstate-trace.h | 96 +++
- drivers/cpufreq/amd-pstate.c | 812 ++++++++++++++++++
+ drivers/cpufreq/amd-pstate.c | 724 ++++++++++++++++++
include/acpi/cppc_acpi.h | 5 +
- tools/power/cpupower/lib/cpufreq.c | 44 +-
- tools/power/cpupower/lib/cpufreq.h | 16 +
- tools/power/cpupower/utils/cpufreq-info.c | 27 +-
+ tools/power/cpupower/lib/cpufreq.c | 21 +-
+ tools/power/cpupower/lib/cpufreq.h | 12 +
+ tools/power/cpupower/utils/cpufreq-info.c | 68 +-
+ tools/power/cpupower/utils/helpers/amd.c | 82 ++
tools/power/cpupower/utils/helpers/cpuid.c | 13 +
- tools/power/cpupower/utils/helpers/helpers.h | 6 +
- tools/power/cpupower/utils/helpers/misc.c | 27 +
- 17 files changed, 1500 insertions(+), 4 deletions(-)
+ tools/power/cpupower/utils/helpers/helpers.h | 21 +
+ tools/power/cpupower/utils/helpers/misc.c | 64 ++
+ 18 files changed, 1514 insertions(+), 58 deletions(-)
create mode 100644 Documentation/admin-guide/pm/amd_pstate.rst
create mode 100644 drivers/cpufreq/amd-pstate-trace.c
create mode 100644 drivers/cpufreq/amd-pstate-trace.h
@@ -740,14 +802,14 @@ index f40994c422dc..28db6156b55d 100644
intel_epb
intel-speed-select
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
-index d0ce5cfd3ac1..f7aea50e3371 100644
+index d0ce5cfd3ac1..f23dc1abd485 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -313,6 +313,7 @@
#define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
-+#define X86_FEATURE_AMD_CPPC_EXT (13*32+27) /* Collaborative Processor Performance Control Extension */
++#define X86_FEATURE_AMD_CPPC (13*32+27) /* Collaborative Processor Performance Control */
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
@@ -780,19 +842,29 @@ index a7c413432b33..ce42e15cf303 100644
#define MSR_F17H_IRPERF 0xc00000e9
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
-index a4d4eebba1da..de4b30545215 100644
+index a4d4eebba1da..b285960c35e7 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
-@@ -1220,6 +1220,48 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
+@@ -411,7 +411,7 @@ bool acpi_cpc_valid(void)
+ struct cpc_desc *cpc_ptr;
+ int cpu;
+
+- for_each_possible_cpu(cpu) {
++ for_each_online_cpu(cpu) {
+ cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
+ if (!cpc_ptr)
+ return false;
+@@ -1220,6 +1220,54 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
}
EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs);
+/**
-+ * cppc_set_enable - Set to enable CPPC register.
++ * cppc_set_enable - Set to enable CPPC on the processor by writing the
++ * Continuous Performance Control package EnableRegister feild.
+ * @cpu: CPU for which to enable CPPC register.
-+ * @enable: enable field to write into share memory.
++ * @enable: 0 - disable, 1 - enable CPPC feature on the processor.
+ *
-+ * Return: 0 for success, -ERRNO otherwise.
++ * Return: 0 for success, -ERRNO or -EIO otherwise.
+ */
+int cppc_set_enable(int cpu, u32 enable)
+{
@@ -802,6 +874,10 @@ index a4d4eebba1da..de4b30545215 100644
+ struct cppc_pcc_data *pcc_ss_data = NULL;
+ int ret = -1;
+
++ /* check the input value*/
++ if (cpu < 0 || cpu > num_possible_cpus() - 1 || enable > 1)
++ return -ENODEV;
++
+ if (!cpc_desc) {
+ pr_debug("No CPC descriptor for CPU:%d\n", cpu);
+ return -ENODEV;
@@ -821,7 +897,8 @@ index a4d4eebba1da..de4b30545215 100644
+ pcc_ss_data = pcc_data[pcc_ss_id];
+
+ down_write(&pcc_ss_data->pcc_lock);
-+ send_pcc_cmd(pcc_ss_id, CMD_WRITE);
++ /* after writing CPC, transfer the ownership of PCC to platfrom */
++ ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE);
+ up_write(&pcc_ss_data->pcc_lock);
+ }
+
@@ -857,7 +934,7 @@ index 92701a18bdd9..9cd7e338bdcd 100644
tristate "ACPI Processor P-States driver"
depends on ACPI_PROCESSOR
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
-index 27d3bd7ea9d4..c1909475eaf9 100644
+index 27d3bd7ea9d4..04882bc4b145 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -17,6 +17,10 @@ obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o
@@ -871,14 +948,14 @@ index 27d3bd7ea9d4..c1909475eaf9 100644
##################################################################################
# x86 drivers.
# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
-@@ -24,6 +28,7 @@ obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o
- # powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers.
+@@ -25,6 +29,7 @@ obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o
# speedstep-* is preferred over p4-clockmod.
-+obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
++obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o
obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
+ obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
diff --git a/drivers/cpufreq/amd-pstate-trace.c b/drivers/cpufreq/amd-pstate-trace.c
new file mode 100644
index 000000000000..891b696dcd69
@@ -991,10 +1068,10 @@ index 000000000000..50c85e150f30
+#include <trace/define_trace.h>
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
new file mode 100644
-index 000000000000..9c60388d45ed
+index 000000000000..b0353d13f74a
--- /dev/null
+++ b/drivers/cpufreq/amd-pstate.c
-@@ -0,0 +1,812 @@
+@@ -0,0 +1,724 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * amd-pstate.c - AMD Processor P-state Frequency Driver
@@ -1033,6 +1110,7 @@ index 000000000000..9c60388d45ed
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
++#include <linux/static_call.h>
+
+#include <acpi/processor.h>
+#include <acpi/cppc_acpi.h>
@@ -1049,8 +1127,7 @@ index 000000000000..9c60388d45ed
+enum switch_type
+{
+ AMD_TARGET = 0,
-+ AMD_ADJUST_PERF,
-+ AMD_FAST_SWITCH,
++ AMD_ADJUST_PERF
+};
+
+static struct cpufreq_driver amd_pstate_driver;
@@ -1076,14 +1153,6 @@ index 000000000000..9c60388d45ed
+ bool boost_supported;
+};
+
-+struct amd_pstate_perf_funcs {
-+ int (*enable)(bool enable);
-+ int (*init_perf)(struct amd_cpudata *cpudata);
-+ void (*update_perf)(struct amd_cpudata *cpudata,
-+ u32 min_perf, u32 des_perf,
-+ u32 max_perf, bool fast_switch);
-+};
-+
+static inline int pstate_enable(bool enable)
+{
+ return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable ? 1 : 0);
@@ -1102,13 +1171,11 @@ index 000000000000..9c60388d45ed
+ return ret;
+}
+
-+static int
-+amd_pstate_enable(struct amd_pstate_perf_funcs *funcs, bool enable)
-+{
-+ if (!funcs)
-+ return -EINVAL;
++DEFINE_STATIC_CALL(amd_pstate_enable, pstate_enable);
+
-+ return funcs->enable(enable);
++static inline int amd_pstate_enable(bool enable)
++{
++ return static_call(amd_pstate_enable)(enable);
+}
+
+static int pstate_init_perf(struct amd_cpudata *cpudata)
@@ -1120,9 +1187,10 @@ index 000000000000..9c60388d45ed
+ if (ret)
+ return ret;
+
-+ /* Some AMD processors has specific power features that the cppc entry
-+ * doesn't indicate the highest performance. It will introduce the
-+ * feature in following days.
++ /*
++ * TODO: Introduce AMD specific power feature.
++ *
++ * CPPC entry doesn't indicate the highest performance in some ASICs.
+ */
+ WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
+
@@ -1151,18 +1219,15 @@ index 000000000000..9c60388d45ed
+ return 0;
+}
+
-+static int amd_pstate_init_perf(struct amd_cpudata *cpudata)
-+{
-+ struct amd_pstate_perf_funcs *funcs = cpufreq_get_driver_data();
-+
-+ if (!funcs)
-+ return -EINVAL;
++DEFINE_STATIC_CALL(amd_pstate_init_perf, pstate_init_perf);
+
-+ return funcs->init_perf(cpudata);
++static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata)
++{
++ return static_call(amd_pstate_init_perf)(cpudata);
+}
+
-+static void pstate_update_perf(struct amd_cpudata *cpudata,
-+ u32 min_perf, u32 des_perf, u32 max_perf,
++static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
++ u32 des_perf, u32 max_perf,
+ bool fast_switch)
+{
+ if (fast_switch)
@@ -1185,28 +1250,23 @@ index 000000000000..9c60388d45ed
+ cppc_set_perf(cpudata->cpu, &perf_ctrls);
+}
+
-+static int
++DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf);
++
++static inline void
+amd_pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
+ u32 des_perf, u32 max_perf, bool fast_switch)
+{
-+ struct amd_pstate_perf_funcs *funcs = cpufreq_get_driver_data();
-+
-+ if (!funcs)
-+ return -EINVAL;
-+
-+ funcs->update_perf(cpudata, min_perf, des_perf,
-+ max_perf, fast_switch);
-+
-+ return 0;
++ static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
++ max_perf, fast_switch);
+}
+
-+static int
++static void
+amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
-+ u32 des_perf, u32 max_perf, bool fast_switch,
-+ enum switch_type type)
++ u32 des_perf, u32 max_perf, bool fast_switch)
+{
+ u64 prev = READ_ONCE(cpudata->cppc_req_cached);
+ u64 value = prev;
++ enum switch_type type = fast_switch ? AMD_ADJUST_PERF : AMD_TARGET;
+
+ value &= ~REQ_MIN_PERF(~0L);
+ value |= REQ_MIN_PERF(min_perf);
@@ -1219,26 +1279,14 @@ index 000000000000..9c60388d45ed
+
+ trace_amd_pstate_perf(min_perf, des_perf, max_perf,
+ cpudata->cpu, prev, value, type);
++
+ if (value == prev)
-+ return 0;
++ return;
+
+ WRITE_ONCE(cpudata->cppc_req_cached, value);
+
-+ return amd_pstate_update_perf(cpudata, min_perf, des_perf,
-+ max_perf, fast_switch);
-+}
-+
-+static bool amd_pstate_boost_supported(struct amd_cpudata *cpudata)
-+{
-+ u32 highest_perf, nominal_perf;
-+
-+ highest_perf = READ_ONCE(cpudata->highest_perf);
-+ nominal_perf = READ_ONCE(cpudata->nominal_perf);
-+
-+ if (highest_perf > nominal_perf)
-+ return true;
-+
-+ return false;
++ amd_pstate_update_perf(cpudata, min_perf, des_perf,
++ max_perf, fast_switch);
+}
+
+static int amd_pstate_verify(struct cpufreq_policy_data *policy)
@@ -1252,7 +1300,6 @@ index 000000000000..9c60388d45ed
+ unsigned int target_freq,
+ unsigned int relation)
+{
-+ int ret;
+ struct cpufreq_freqs freqs;
+ struct amd_cpudata *cpudata = policy->driver_data;
+ unsigned long amd_max_perf, amd_min_perf, amd_des_perf,
@@ -1272,11 +1319,11 @@ index 000000000000..9c60388d45ed
+ cpudata->max_freq);
+
+ cpufreq_freq_transition_begin(policy, &freqs);
-+ ret = amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-+ amd_max_perf, false, AMD_TARGET);
++ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
++ amd_max_perf, false);
+ cpufreq_freq_transition_end(policy, &freqs, false);
+
-+ return ret;
++ return 0;
+}
+
+static void amd_pstate_adjust_perf(unsigned int cpu,
@@ -1311,32 +1358,7 @@ index 000000000000..9c60388d45ed
+ amd_min_perf, amd_max_perf);
+
+ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-+ amd_max_perf, true, AMD_ADJUST_PERF);
-+}
-+
-+static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy,
-+ unsigned int target_freq)
-+{
-+ u64 ratio;
-+ struct amd_cpudata *cpudata = policy->driver_data;
-+ unsigned long amd_max_perf, amd_min_perf, amd_des_perf, nominal_perf;
-+
-+ if (!cpudata->max_freq)
-+ return -ENODEV;
-+
-+ amd_max_perf = READ_ONCE(cpudata->highest_perf);
-+ amd_min_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
-+
-+ amd_des_perf = DIV_ROUND_UP(target_freq * amd_max_perf,
-+ cpudata->max_freq);
-+
-+ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf,
-+ amd_max_perf, true, AMD_FAST_SWITCH);
-+
-+ nominal_perf = READ_ONCE(cpudata->nominal_perf);
-+ ratio = div_u64(amd_des_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
-+
-+ return cpudata->nominal_freq * ratio >> SCHED_CAPACITY_SHIFT;
++ amd_max_perf, true);
+}
+
+static int amd_get_min_freq(struct amd_cpudata *cpudata)
@@ -1441,6 +1463,14 @@ index 000000000000..9c60388d45ed
+
+static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
+{
++ u32 highest_perf, nominal_perf;
++
++ highest_perf = READ_ONCE(cpudata->highest_perf);
++ nominal_perf = READ_ONCE(cpudata->nominal_perf);
++
++ if (highest_perf <= nominal_perf)
++ return;
++
+ cpudata->boost_supported = true;
+ amd_pstate_driver.boost_enabled = true;
+}
@@ -1462,18 +1492,6 @@ index 000000000000..9c60388d45ed
+ return 0;
+}
+
-+static struct amd_pstate_perf_funcs pstate_funcs = {
-+ .enable = pstate_enable,
-+ .init_perf = pstate_init_perf,
-+ .update_perf = pstate_update_perf,
-+};
-+
-+static struct amd_pstate_perf_funcs cppc_funcs = {
-+ .enable = cppc_enable,
-+ .init_perf = cppc_init_perf,
-+ .update_perf = cppc_update_perf,
-+};
-+
+static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+{
+ int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
@@ -1520,7 +1538,7 @@ index 000000000000..9c60388d45ed
+ /* It will be updated by governor */
+ policy->cur = policy->cpuinfo.min_freq;
+
-+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT))
++ if (boot_cpu_has(X86_FEATURE_AMD_CPPC))
+ policy->fast_switch_possible = true;
+
+ ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
@@ -1547,8 +1565,7 @@ index 000000000000..9c60388d45ed
+
+ policy->driver_data = cpudata;
+
-+ if (amd_pstate_boost_supported(cpudata))
-+ amd_pstate_boost_init(cpudata);
++ amd_pstate_boost_init(cpudata);
+
+ return 0;
+
@@ -1579,7 +1596,7 @@ index 000000000000..9c60388d45ed
+static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy,
+ char *buf)
+{
-+ int ret = 0, max_freq;
++ int max_freq;
+ struct amd_cpudata *cpudata;
+
+ cpudata = policy->driver_data;
@@ -1588,15 +1605,13 @@ index 000000000000..9c60388d45ed
+ if (max_freq < 0)
+ return max_freq;
+
-+ ret += sprintf(&buf[ret], "%u\n", max_freq);
-+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", max_freq);
+}
+
+static ssize_t show_amd_pstate_nominal_freq(struct cpufreq_policy *policy,
+ char *buf)
+{
-+ int ret = 0, nominal_freq;
++ int nominal_freq;
+ struct amd_cpudata *cpudata;
+
+ cpudata = policy->driver_data;
@@ -1605,15 +1620,13 @@ index 000000000000..9c60388d45ed
+ if (nominal_freq < 0)
+ return nominal_freq;
+
-+ ret += sprintf(&buf[ret], "%u\n", nominal_freq);
-+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", nominal_freq);
+}
+
+static ssize_t
+show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *policy, char *buf)
+{
-+ int ret = 0, freq;
++ int freq;
+ struct amd_cpudata *cpudata;
+
+ cpudata = policy->driver_data;
@@ -1622,82 +1635,65 @@ index 000000000000..9c60388d45ed
+ if (freq < 0)
+ return freq;
+
-+ ret += sprintf(&buf[ret], "%u\n", freq);
-+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", freq);
+}
+
+static ssize_t show_amd_pstate_min_freq(struct cpufreq_policy *policy, char *buf)
+{
-+ int ret = 0;
-+ int freq;
++ int min_freq;
+ struct amd_cpudata *cpudata;
+
+ cpudata = policy->driver_data;
+
-+ freq = amd_get_min_freq(cpudata);
-+ if (freq < 0)
-+ return freq;
-+
-+ ret += sprintf(&buf[ret], "%u\n", freq);
++ min_freq = amd_get_min_freq(cpudata);
++ if (min_freq < 0)
++ return min_freq;
+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", min_freq);
+}
+
+static ssize_t
+show_amd_pstate_highest_perf(struct cpufreq_policy *policy, char *buf)
+{
-+ int ret = 0;
+ u32 perf;
+ struct amd_cpudata *cpudata = policy->driver_data;
+
+ perf = READ_ONCE(cpudata->highest_perf);
+
-+ ret += sprintf(&buf[ret], "%u\n", perf);
-+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", perf);
+}
+
+static ssize_t
+show_amd_pstate_nominal_perf(struct cpufreq_policy *policy, char *buf)
+{
-+ int ret = 0;
+ u32 perf;
+ struct amd_cpudata *cpudata = policy->driver_data;
+
+ perf = READ_ONCE(cpudata->nominal_perf);
+
-+ ret += sprintf(&buf[ret], "%u\n", perf);
-+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", perf);
+}
+
+static ssize_t
+show_amd_pstate_lowest_nonlinear_perf(struct cpufreq_policy *policy, char *buf)
+{
-+ int ret = 0;
+ u32 perf;
+ struct amd_cpudata *cpudata = policy->driver_data;
+
+ perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
+
-+ ret += sprintf(&buf[ret], "%u\n", perf);
-+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", perf);
+}
+
+static ssize_t
+show_amd_pstate_lowest_perf(struct cpufreq_policy *policy, char *buf)
+{
-+ int ret = 0;
+ u32 perf;
+ struct amd_cpudata *cpudata = policy->driver_data;
+
+ perf = READ_ONCE(cpudata->lowest_perf);
+
-+ ret += sprintf(&buf[ret], "%u\n", perf);
-+
-+ return ret;
++ return sprintf(&buf[0], "%u\n", perf);
+}
+
+static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy,
@@ -1735,7 +1731,6 @@ index 000000000000..9c60388d45ed
+ .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
+ .verify = amd_pstate_verify,
+ .target = amd_pstate_target,
-+ .fast_switch = amd_pstate_fast_switch,
+ .init = amd_pstate_cpu_init,
+ .exit = amd_pstate_cpu_exit,
+ .set_boost = amd_pstate_set_boost,
@@ -1746,7 +1741,6 @@ index 000000000000..9c60388d45ed
+static int __init amd_pstate_init(void)
+{
+ int ret;
-+ struct amd_pstate_perf_funcs *funcs;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return -ENODEV;
@@ -1762,25 +1756,24 @@ index 000000000000..9c60388d45ed
+ return -EEXIST;
+
+ /* capability check */
-+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC_EXT)) {
-+ pr_debug("%s, AMD CPPC extension functionality is supported\n",
++ if (boot_cpu_has(X86_FEATURE_AMD_CPPC)) {
++ pr_debug("%s, AMD CPPC MSR based functionality is supported\n",
+ __func__);
-+ funcs = &pstate_funcs;
+ amd_pstate_driver.adjust_perf = amd_pstate_adjust_perf;
+ } else {
-+ funcs = &cppc_funcs;
++ static_call_update(amd_pstate_enable, cppc_enable);
++ static_call_update(amd_pstate_init_perf, cppc_init_perf);
++ static_call_update(amd_pstate_update_perf, cppc_update_perf);
+ }
+
+ /* enable amd pstate feature */
-+ ret = amd_pstate_enable(funcs, true);
++ ret = amd_pstate_enable(true);
+ if (ret) {
+ pr_err("%s, failed to enable amd-pstate with return %d\n",
+ __func__, ret);
+ return ret;
+ }
+
-+ amd_pstate_driver.driver_data = funcs;
-+
+ ret = cpufreq_register_driver(&amd_pstate_driver);
+ if (ret) {
+ pr_err("%s, return %d\n", __func__, ret);
@@ -1792,13 +1785,9 @@ index 000000000000..9c60388d45ed
+
+static void __exit amd_pstate_exit(void)
+{
-+ struct amd_pstate_perf_funcs *funcs;
-+
-+ funcs = cpufreq_get_driver_data();
-+
+ cpufreq_unregister_driver(&amd_pstate_driver);
+
-+ amd_pstate_enable(funcs, false);
++ amd_pstate_enable(false);
+}
+
+module_init(amd_pstate_init);
@@ -1831,103 +1820,124 @@ index 9f4985b4d64d..3fdae40a75fc 100644
{
return -ENOTSUPP;
diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c
-index c3b56db8b921..1443080868da 100644
+index c3b56db8b921..02719cc400a1 100644
--- a/tools/power/cpupower/lib/cpufreq.c
+++ b/tools/power/cpupower/lib/cpufreq.c
-@@ -69,6 +69,14 @@ enum cpufreq_value {
- SCALING_MIN_FREQ,
- SCALING_MAX_FREQ,
- STATS_NUM_TRANSITIONS,
-+ AMD_PSTATE_HIGHEST_PERF,
-+ AMD_PSTATE_NOMINAL_PERF,
-+ AMD_PSTATE_LOWEST_NONLINEAR_PERF,
-+ AMD_PSTATE_LOWEST_PERF,
-+ AMD_PSTATE_MAX_FREQ,
-+ AMD_PSTATE_NOMINAL_FREQ,
-+ AMD_PSTATE_LOWEST_NONLINEAR_FREQ,
-+ AMD_PSTATE_MIN_FREQ,
- MAX_CPUFREQ_VALUE_READ_FILES
+@@ -83,20 +83,21 @@ static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = {
+ [STATS_NUM_TRANSITIONS] = "stats/total_trans"
};
-@@ -80,7 +88,15 @@ static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = {
- [SCALING_CUR_FREQ] = "scaling_cur_freq",
- [SCALING_MIN_FREQ] = "scaling_min_freq",
- [SCALING_MAX_FREQ] = "scaling_max_freq",
-- [STATS_NUM_TRANSITIONS] = "stats/total_trans"
-+ [STATS_NUM_TRANSITIONS] = "stats/total_trans",
-+ [AMD_PSTATE_HIGHEST_PERF] = "amd_pstate_highest_perf",
-+ [AMD_PSTATE_NOMINAL_PERF] = "amd_pstate_nominal_perf",
-+ [AMD_PSTATE_LOWEST_NONLINEAR_PERF] = "amd_pstate_lowest_nonlinear_perf",
-+ [AMD_PSTATE_LOWEST_PERF] = "amd_pstate_lowest_perf",
-+ [AMD_PSTATE_MAX_FREQ] = "amd_pstate_max_freq",
-+ [AMD_PSTATE_NOMINAL_FREQ] = "amd_pstate_nominal_freq",
-+ [AMD_PSTATE_LOWEST_NONLINEAR_FREQ] = "amd_pstate_lowest_nonlinear_freq",
-+ [AMD_PSTATE_MIN_FREQ] = "amd_pstate_min_freq"
- };
+-
+-static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu,
+- enum cpufreq_value which)
++unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu,
++ const char **table,
++ unsigned index,
++ unsigned size)
+ {
+ unsigned long value;
+ unsigned int len;
+ char linebuf[MAX_LINE_LEN];
+ char *endp;
+- if (which >= MAX_CPUFREQ_VALUE_READ_FILES)
++ if (!table && !table[index] && index >= size)
+ return 0;
-@@ -774,3 +790,29 @@ unsigned long cpufreq_get_transitions(unsigned int cpu)
- {
- return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS);
+- len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which],
+- linebuf, sizeof(linebuf));
++ len = sysfs_cpufreq_read_file(cpu, table[index], linebuf,
++ sizeof(linebuf));
+
+ if (len == 0)
+ return 0;
+@@ -109,6 +110,14 @@ static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu,
+ return value;
}
-+
-+int amd_pstate_boost_support(unsigned int cpu)
-+{
-+ unsigned int highest_perf, nominal_perf;
-+
-+ highest_perf = sysfs_cpufreq_get_one_value(cpu, AMD_PSTATE_HIGHEST_PERF);
-+ nominal_perf = sysfs_cpufreq_get_one_value(cpu, AMD_PSTATE_NOMINAL_PERF);
-+
-+ return highest_perf > nominal_perf ? 1 : 0;
-+}
-+
-+int amd_pstate_boost_enabled(unsigned int cpu)
+
++static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu,
++ enum cpufreq_value which)
+{
-+ unsigned int cpuinfo_max, amd_pstate_max;
-+
-+ cpuinfo_max = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MAX_FREQ);
-+ amd_pstate_max = sysfs_cpufreq_get_one_value(cpu, AMD_PSTATE_MAX_FREQ);
-+
-+ return cpuinfo_max == amd_pstate_max ? 1 : 0;
++ return cpufreq_get_sysfs_value_from_table(cpu, cpufreq_value_files,
++ which,
++ MAX_CPUFREQ_VALUE_READ_FILES);
+}
+
-+unsigned amd_pstate_get_data(unsigned int cpu, enum amd_pstate_param param)
-+{
-+ return sysfs_cpufreq_get_one_value(cpu,
-+ param + AMD_PSTATE_HIGHEST_PERF);
-+}
+ /* read access to files which contain one string */
+
+ enum cpufreq_string {
diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h
-index 95f4fd9e2656..954e72704fc0 100644
+index 95f4fd9e2656..107668c0c454 100644
--- a/tools/power/cpupower/lib/cpufreq.h
+++ b/tools/power/cpupower/lib/cpufreq.h
-@@ -203,6 +203,22 @@ int cpufreq_modify_policy_governor(unsigned int cpu, char *governor);
+@@ -203,6 +203,18 @@ int cpufreq_modify_policy_governor(unsigned int cpu, char *governor);
int cpufreq_set_frequency(unsigned int cpu,
unsigned long target_frequency);
-+int amd_pstate_boost_support(unsigned int cpu);
-+int amd_pstate_boost_enabled(unsigned int cpu);
-+
-+enum amd_pstate_param {
-+ HIGHEST_PERF,
-+ NOMINAL_PERF,
-+ LOWEST_NONLINEAR_PERF,
-+ LOWEST_PERF,
-+ MAX_FREQ,
-+ NOMINAL_FREQ,
-+ LOWEST_NONLINEAR_FREQ,
-+ MIN_FREQ,
-+};
++/*
++ * get the sysfs value from specific table
++ *
++ * Read the value with the sysfs file name from specific table. Does
++ * only work if the cpufreq driver has the specific sysfs interfaces.
++ */
+
-+unsigned amd_pstate_get_data(unsigned int cpu, enum amd_pstate_param param);
++unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu,
++ const char **table,
++ unsigned index,
++ unsigned size);
+
#ifdef __cplusplus
}
#endif
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
-index f9895e31ff5a..9eabed209adc 100644
+index f9895e31ff5a..f828f3c35a6f 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
+++ b/tools/power/cpupower/utils/cpufreq-info.c
-@@ -183,9 +183,30 @@ static int get_boost_mode_x86(unsigned int cpu)
+@@ -84,43 +84,6 @@ static void proc_cpufreq_output(void)
+ }
+
+ static int no_rounding;
+-static void print_speed(unsigned long speed)
+-{
+- unsigned long tmp;
+-
+- if (no_rounding) {
+- if (speed > 1000000)
+- printf("%u.%06u GHz", ((unsigned int) speed/1000000),
+- ((unsigned int) speed%1000000));
+- else if (speed > 1000)
+- printf("%u.%03u MHz", ((unsigned int) speed/1000),
+- (unsigned int) (speed%1000));
+- else
+- printf("%lu kHz", speed);
+- } else {
+- if (speed > 1000000) {
+- tmp = speed%10000;
+- if (tmp >= 5000)
+- speed += 10000;
+- printf("%u.%02u GHz", ((unsigned int) speed/1000000),
+- ((unsigned int) (speed%1000000)/10000));
+- } else if (speed > 100000) {
+- tmp = speed%1000;
+- if (tmp >= 500)
+- speed += 1000;
+- printf("%u MHz", ((unsigned int) speed/1000));
+- } else if (speed > 1000) {
+- tmp = speed%100;
+- if (tmp >= 50)
+- speed += 100;
+- printf("%u.%01u MHz", ((unsigned int) speed/1000),
+- ((unsigned int) (speed%1000)/100));
+- }
+- }
+-
+- return;
+-}
+-
+ static void print_duration(unsigned long duration)
+ {
+ unsigned long tmp;
+@@ -183,9 +146,12 @@ static int get_boost_mode_x86(unsigned int cpu)
printf(_(" Supported: %s\n"), support ? _("yes") : _("no"));
printf(_(" Active: %s\n"), active ? _("yes") : _("no"));
@@ -1936,33 +1946,193 @@ index f9895e31ff5a..9eabed209adc 100644
- cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
+ if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
+ cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) {
-+ printf(_(" AMD PSTATE Highest Performance: %u. Maximum Frequency: "),
-+ amd_pstate_get_data(cpu, HIGHEST_PERF));
-+ print_speed(amd_pstate_get_data(cpu, MAX_FREQ));
-+ printf(".\n");
-+
-+ printf(_(" AMD PSTATE Nominal Performance: %u. Nominal Frequency: "),
-+ amd_pstate_get_data(cpu, NOMINAL_PERF));
-+ print_speed(amd_pstate_get_data(cpu, NOMINAL_FREQ));
-+ printf(".\n");
-+
-+ printf(_(" AMD PSTATE Lowest Non-linear Performance: %u. Lowest Non-linear Frequency: "),
-+ amd_pstate_get_data(cpu, LOWEST_NONLINEAR_PERF));
-+ print_speed(amd_pstate_get_data(cpu, LOWEST_NONLINEAR_FREQ));
-+ printf(".\n");
-+
-+ printf(_(" AMD PSTATE Lowest Performance: %u. Lowest Frequency: "),
-+ amd_pstate_get_data(cpu, LOWEST_PERF));
-+ print_speed(amd_pstate_get_data(cpu, MIN_FREQ));
-+ printf(".\n");
++ amd_pstate_show_perf_and_freq(cpu, no_rounding);
+ } else if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
+ cpupower_cpu_info.family >= 0x10) ||
+ cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
ret = decode_pstates(cpu, b_states, pstates, &pstate_no);
if (ret)
return ret;
+@@ -254,11 +220,11 @@ static int get_boost_mode(unsigned int cpu)
+ if (freqs) {
+ printf(_(" boost frequency steps: "));
+ while (freqs->next) {
+- print_speed(freqs->frequency);
++ print_speed(freqs->frequency, no_rounding);
+ printf(", ");
+ freqs = freqs->next;
+ }
+- print_speed(freqs->frequency);
++ print_speed(freqs->frequency, no_rounding);
+ printf("\n");
+ cpufreq_put_available_frequencies(freqs);
+ }
+@@ -277,7 +243,7 @@ static int get_freq_kernel(unsigned int cpu, unsigned int human)
+ return -EINVAL;
+ }
+ if (human) {
+- print_speed(freq);
++ print_speed(freq, no_rounding);
+ } else
+ printf("%lu", freq);
+ printf(_(" (asserted by call to kernel)\n"));
+@@ -296,7 +262,7 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human)
+ return -EINVAL;
+ }
+ if (human) {
+- print_speed(freq);
++ print_speed(freq, no_rounding);
+ } else
+ printf("%lu", freq);
+ printf(_(" (asserted by call to hardware)\n"));
+@@ -316,9 +282,9 @@ static int get_hardware_limits(unsigned int cpu, unsigned int human)
+
+ if (human) {
+ printf(_(" hardware limits: "));
+- print_speed(min);
++ print_speed(min, no_rounding);
+ printf(" - ");
+- print_speed(max);
++ print_speed(max, no_rounding);
+ printf("\n");
+ } else {
+ printf("%lu %lu\n", min, max);
+@@ -350,9 +316,9 @@ static int get_policy(unsigned int cpu)
+ return -EINVAL;
+ }
+ printf(_(" current policy: frequency should be within "));
+- print_speed(policy->min);
++ print_speed(policy->min, no_rounding);
+ printf(_(" and "));
+- print_speed(policy->max);
++ print_speed(policy->max, no_rounding);
+
+ printf(".\n ");
+ printf(_("The governor \"%s\" may decide which speed to use\n"
+@@ -436,7 +402,7 @@ static int get_freq_stats(unsigned int cpu, unsigned int human)
+ struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time);
+ while (stats) {
+ if (human) {
+- print_speed(stats->frequency);
++ print_speed(stats->frequency, no_rounding);
+ printf(":%.2f%%",
+ (100.0 * stats->time_in_state) / total_time);
+ } else
+@@ -486,11 +452,11 @@ static void debug_output_one(unsigned int cpu)
+ if (freqs) {
+ printf(_(" available frequency steps: "));
+ while (freqs->next) {
+- print_speed(freqs->frequency);
++ print_speed(freqs->frequency, no_rounding);
+ printf(", ");
+ freqs = freqs->next;
+ }
+- print_speed(freqs->frequency);
++ print_speed(freqs->frequency, no_rounding);
+ printf("\n");
+ cpufreq_put_available_frequencies(freqs);
+ }
+diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c
+index 97f2c857048e..d68d052ee4cb 100644
+--- a/tools/power/cpupower/utils/helpers/amd.c
++++ b/tools/power/cpupower/utils/helpers/amd.c
+@@ -8,7 +8,9 @@
+ #include <pci/pci.h>
+
+ #include "helpers/helpers.h"
++#include "cpufreq.h"
+
++/* ACPI P-States Helper Functions for AMD Processors ***************/
+ #define MSR_AMD_PSTATE_STATUS 0xc0010063
+ #define MSR_AMD_PSTATE 0xc0010064
+ #define MSR_AMD_PSTATE_LIMIT 0xc0010061
+@@ -146,4 +148,84 @@ int amd_pci_get_num_boost_states(int *active, int *states)
+ pci_cleanup(pci_acc);
+ return 0;
+ }
++
++/* ACPI P-States Helper Functions for AMD Processors ***************/
++
++/* AMD P-States Helper Functions ***************/
++enum amd_pstate_value {
++ AMD_PSTATE_HIGHEST_PERF,
++ AMD_PSTATE_NOMINAL_PERF,
++ AMD_PSTATE_LOWEST_NONLINEAR_PERF,
++ AMD_PSTATE_LOWEST_PERF,
++ AMD_PSTATE_MAX_FREQ,
++ AMD_PSTATE_NOMINAL_FREQ,
++ AMD_PSTATE_LOWEST_NONLINEAR_FREQ,
++ AMD_PSTATE_MIN_FREQ,
++ MAX_AMD_PSTATE_VALUE_READ_FILES
++};
++
++static const char *amd_pstate_value_files[MAX_AMD_PSTATE_VALUE_READ_FILES] = {
++ [AMD_PSTATE_HIGHEST_PERF] = "amd_pstate_highest_perf",
++ [AMD_PSTATE_NOMINAL_PERF] = "amd_pstate_nominal_perf",
++ [AMD_PSTATE_LOWEST_NONLINEAR_PERF] = "amd_pstate_lowest_nonlinear_perf",
++ [AMD_PSTATE_LOWEST_PERF] = "amd_pstate_lowest_perf",
++ [AMD_PSTATE_MAX_FREQ] = "amd_pstate_max_freq",
++ [AMD_PSTATE_NOMINAL_FREQ] = "amd_pstate_nominal_freq",
++ [AMD_PSTATE_LOWEST_NONLINEAR_FREQ] = "amd_pstate_lowest_nonlinear_freq",
++ [AMD_PSTATE_MIN_FREQ] = "amd_pstate_min_freq"
++};
++
++static unsigned long amd_pstate_get_data(unsigned int cpu,
++ enum amd_pstate_value value)
++{
++ return cpufreq_get_sysfs_value_from_table(cpu,
++ amd_pstate_value_files,
++ value,
++ MAX_AMD_PSTATE_VALUE_READ_FILES);
++}
++
++void amd_pstate_boost_init(unsigned int cpu, int *support, int *active)
++{
++ unsigned long highest_perf, nominal_perf, cpuinfo_min,
++ cpuinfo_max, amd_pstate_max;
++
++ highest_perf = amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF);
++ nominal_perf = amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_PERF);
++
++ *support = highest_perf > nominal_perf ? 1 : 0;
++ if (!(*support))
++ return;
++
++ cpufreq_get_hardware_limits(cpu, &cpuinfo_min, &cpuinfo_max);
++ amd_pstate_max = amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ);
++
++ *active = cpuinfo_max == amd_pstate_max ? 1 : 0;
++}
++
++void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding)
++{
++ printf(_(" AMD PSTATE Highest Performance: %lu. Maximum Frequency: "),
++ amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF));
++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ), no_rounding);
++ printf(".\n");
++
++ printf(_(" AMD PSTATE Nominal Performance: %lu. Nominal Frequency: "),
++ amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_PERF));
++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_FREQ),
++ no_rounding);
++ printf(".\n");
++
++ printf(_(" AMD PSTATE Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "),
++ amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_NONLINEAR_PERF));
++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_NONLINEAR_FREQ),
++ no_rounding);
++ printf(".\n");
++
++ printf(_(" AMD PSTATE Lowest Performance: %lu. Lowest Frequency: "),
++ amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_PERF));
++ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MIN_FREQ), no_rounding);
++ printf(".\n");
++}
++
++/* AMD P-States Helper Functions ***************/
+ #endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
-index 72eb43593180..78218c54acca 100644
+index 72eb43593180..2a6dc104e76b 100644
--- a/tools/power/cpupower/utils/helpers/cpuid.c
+++ b/tools/power/cpupower/utils/helpers/cpuid.c
@@ -149,6 +149,19 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info)
@@ -1970,7 +2140,7 @@ index 72eb43593180..78218c54acca 100644
cpuid_ebx(0x80000008) & (1 << 4))
cpu_info->caps |= CPUPOWER_CAP_AMD_RDPRU;
+
-+ if (cpupower_amd_pstate_enabled(0)) {
++ if (cpupower_amd_pstate_enabled()) {
+ cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE;
+
+ /*
@@ -1986,7 +2156,7 @@ index 72eb43593180..78218c54acca 100644
if (cpu_info->vendor == X86_VENDOR_INTEL) {
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
-index 33ffacee7fcb..eb43c14d1728 100644
+index 33ffacee7fcb..80755568afc4 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -73,6 +73,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
@@ -1997,48 +2167,64 @@ index 33ffacee7fcb..eb43c14d1728 100644
#define CPUPOWER_AMD_CPBDIS 0x02000000
-@@ -135,6 +136,11 @@ extern int decode_pstates(unsigned int cpu, int boost_states,
+@@ -135,6 +136,16 @@ extern int decode_pstates(unsigned int cpu, int boost_states,
extern int cpufreq_has_boost_support(unsigned int cpu, int *support,
int *active, int * states);
+
-+/* AMD PSTATE enabling **************************/
++/* AMD P-States stuff **************************/
++extern unsigned long cpupower_amd_pstate_enabled(void);
++extern void amd_pstate_boost_init(unsigned int cpu,
++ int *support, int *active);
++extern void amd_pstate_show_perf_and_freq(unsigned int cpu,
++ int no_rounding);
+
-+extern unsigned long cpupower_amd_pstate_enabled(unsigned int cpu);
++/* AMD P-States stuff **************************/
+
/*
* CPUID functions returning a single datum
*/
-diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
-index fc6e34511721..aba979320760 100644
---- a/tools/power/cpupower/utils/helpers/misc.c
-+++ b/tools/power/cpupower/utils/helpers/misc.c
-@@ -10,6 +10,7 @@
- #if defined(__i386__) || defined(__x86_64__)
+@@ -167,6 +178,15 @@ static inline int cpufreq_has_boost_support(unsigned int cpu, int *support,
+ int *active, int * states)
+ { return -1; }
- #include "cpupower_intern.h"
-+#include "cpufreq.h"
++static inline unsigned long cpupower_amd_pstate_enabled(void)
++{ return 0; }
++static void amd_pstate_boost_init(unsigned int cpu,
++ int *support, int *active)
++{ return; }
++static inline void amd_pstate_show_perf_and_freq(unsigned int cpu,
++ int no_rounding)
++{ return; }
++
+ /* cpuid and cpuinfo helpers **************************/
- #define MSR_AMD_HWCR 0xc0010015
+ static inline unsigned int cpuid_eax(unsigned int op) { return 0; };
+@@ -184,5 +204,6 @@ extern struct bitmask *offline_cpus;
+ void get_cpustate(void);
+ void print_online_cpus(void);
+ void print_offline_cpus(void);
++void print_speed(unsigned long speed, int no_rounding);
-@@ -39,6 +40,12 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
+ #endif /* __CPUPOWERUTILS_HELPERS__ */
+diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
+index fc6e34511721..730f670ab90d 100644
+--- a/tools/power/cpupower/utils/helpers/misc.c
++++ b/tools/power/cpupower/utils/helpers/misc.c
+@@ -39,6 +39,8 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
if (ret)
return ret;
}
-+ } if ((cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) &&
-+ amd_pstate_boost_support(cpu)) {
-+ *support = 1;
-+
-+ if (amd_pstate_boost_enabled(cpu))
-+ *active = 1;
++ } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) {
++ amd_pstate_boost_init(cpu, support, active);
} else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA)
*support = *active = 1;
return 0;
-@@ -83,6 +90,26 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val)
+@@ -83,6 +85,26 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val)
return 0;
}
-+unsigned long cpupower_amd_pstate_enabled(unsigned int cpu)
++unsigned long cpupower_amd_pstate_enabled(void)
+{
+ char linebuf[MAX_LINE_LEN];
+ char path[SYSFS_PATH_MAX];
@@ -2046,7 +2232,7 @@ index fc6e34511721..aba979320760 100644
+ char *endp;
+
+ snprintf(path, sizeof(path),
-+ PATH_TO_CPU "cpu%u/cpufreq/is_amd_pstate_enabled", cpu);
++ PATH_TO_CPU "cpu0/cpufreq/is_amd_pstate_enabled");
+
+ if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0)
+ return 0;
@@ -2061,6 +2247,52 @@ index fc6e34511721..aba979320760 100644
#endif /* #if defined(__i386__) || defined(__x86_64__) */
/* get_cpustate
+@@ -144,3 +166,45 @@ void print_offline_cpus(void)
+ printf(_("cpupower set operation was not performed on them\n"));
+ }
+ }
++
++/*
++ * print_speed
++ *
++ * Print the exact CPU frequency with appropriate unit
++ */
++void print_speed(unsigned long speed, int no_rounding)
++{
++ unsigned long tmp;
++
++ if (no_rounding) {
++ if (speed > 1000000)
++ printf("%u.%06u GHz", ((unsigned int) speed/1000000),
++ ((unsigned int) speed%1000000));
++ else if (speed > 1000)
++ printf("%u.%03u MHz", ((unsigned int) speed/1000),
++ (unsigned int) (speed%1000));
++ else
++ printf("%lu kHz", speed);
++ } else {
++ if (speed > 1000000) {
++ tmp = speed%10000;
++ if (tmp >= 5000)
++ speed += 10000;
++ printf("%u.%02u GHz", ((unsigned int) speed/1000000),
++ ((unsigned int) (speed%1000000)/10000));
++ } else if (speed > 100000) {
++ tmp = speed%1000;
++ if (tmp >= 500)
++ speed += 1000;
++ printf("%u MHz", ((unsigned int) speed/1000));
++ } else if (speed > 1000) {
++ tmp = speed%100;
++ if (tmp >= 50)
++ speed += 100;
++ printf("%u.%01u MHz", ((unsigned int) speed/1000),
++ ((unsigned int) (speed%1000)/100));
++ }
++ }
++
++ return;
++}
--
2.33.0
diff --git a/sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch b/sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch
new file mode 100644
index 000000000000..c77aa387e8b4
--- /dev/null
+++ b/sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch
@@ -0,0 +1,36 @@
+From c5d0ba7e96f765859bb2ddbd5fc0407d7e6e7124 Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+Date: Fri, 24 Sep 2021 12:32:06 -0500
+Subject: [PATCH 1/2] ACPI: PM: s2idle: Don't report missing devices as failing
+ constraints
+
+ACPI tables may have entries for devices that are not physically
+present but that can be connected. These devices shouldn't cause
+constraints checking to fail.
+
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Change-Id: I34f5ca978aab69ff0a0906191eec21649b19fe27
+---
+ drivers/acpi/x86/s2idle.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
+index bd92b549fd5a..c8d4f7909fa9 100644
+--- a/drivers/acpi/x86/s2idle.c
++++ b/drivers/acpi/x86/s2idle.c
+@@ -309,6 +309,12 @@ static void lpi_check_constraints(void)
+ continue;
+ }
+
++ if (!acpi_get_first_physical_node(adev)) {
++ acpi_handle_debug(handle, "LPI: Device is not physically present\n");
++ lpi_constraints_table[i].handle = NULL;
++ continue;
++ }
++
+ if (adev->power.state < lpi_constraints_table[i].min_dstate)
+ acpi_handle_info(handle,
+ "LPI: Constraint not met; min power state:%s current power state:%s\n",
+--
+2.25.1
+
diff --git a/sys-kernel_arch-sources-g14_files-9010-amd-apci-allow-c3.patch b/sys-kernel_arch-sources-g14_files-9010-amd-apci-allow-c3.patch
deleted file mode 100644
index 64bca0b29482..000000000000
--- a/sys-kernel_arch-sources-g14_files-9010-amd-apci-allow-c3.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 52841ba456b08f0f76b2bf26fa7caba18166cdd9 Mon Sep 17 00:00:00 2001
-From: Mario Limonciello <mario.limonciello@amd.com>
-Date: Wed, 15 Sep 2021 16:52:16 -0500
-Subject: [PATCH] ACPI: processor idle: Allow playing dead in C3
-
-commit 1a022e3f1be1 ("idle, x86: Allow off-lined CPU to enter
-deeper C states") originally allowed offlined CPUs to play dead
-up to ACPI C2. Although this improves power consumption of offlined
-CPUs, it does not allow the CPUs to get into the deepest state
-on AMD platforms blocking s0i3 entry.
-
-BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1708
-Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
----
- drivers/acpi/processor_idle.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
-index 095c8aca141e..1b6529396371 100644
---- a/drivers/acpi/processor_idle.c
-+++ b/drivers/acpi/processor_idle.c
-@@ -789,7 +789,8 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
- state->enter = acpi_idle_enter;
-
- state->flags = 0;
-- if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) {
-+ if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2
-+ || cx->type == ACPI_STATE_C3) {
- state->enter_dead = acpi_idle_play_dead;
- drv->safe_state_index = count;
- }
---
-2.25.1
-