diff options
author | egnappahz | 2021-06-08 17:20:15 +0200 |
---|---|---|
committer | egnappahz | 2021-06-08 17:20:15 +0200 |
commit | 7f38799ede8c0dfe277e88d695cd3dbd1c76aa08 (patch) | |
tree | 446e6175a690dc1e5caa43cd1af0cab2deed98a3 /suspend.patch | |
parent | 37d41f523e4cd683f19a466a32990604f7cd5096 (diff) | |
download | aur-7f38799ede8c0dfe277e88d695cd3dbd1c76aa08.tar.gz |
Implemented suspend patches thx 2 gofree
Diffstat (limited to 'suspend.patch')
-rw-r--r-- | suspend.patch | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/suspend.patch b/suspend.patch new file mode 100644 index 000000000000..b5af32b058c9 --- /dev/null +++ b/suspend.patch @@ -0,0 +1,429 @@ +From 65ea8f2c6e230bdf71fed0137cf9e9d1b307db32 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello <mario.limonciello@amd.com> +Date: Wed, 12 May 2021 17:15:14 -0500 +Subject: ACPI: processor idle: Fix up C-state latency if not ordered + +Generally, the C-state latency is provided by the _CST method or +FADT, but some OEM platforms using AMD Picasso, Renoir, Van Gogh, +and Cezanne set the C2 latency greater than C3's which causes the +C2 state to be skipped. + +That will block the core entering PC6, which prevents S0ix working +properly on Linux systems. + +In other operating systems, the latency values are not validated and +this does not cause problems by skipping states. + +To avoid this issue on Linux, detect when latencies are not an +arithmetic progression and sort them. + +Link: https://gitlab.freedesktop.org/agd5f/linux/-/commit/026d186e4592c1ee9c1cb44295912d0294508725 +Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1230#note_712174 +Suggested-by: Prike Liang <Prike.Liang@amd.com> +Suggested-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> +[ rjw: Subject and changelog edits ] +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +--- + drivers/acpi/processor_idle.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 45a019619e4a5..095c8aca141eb 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -16,6 +16,7 @@ + #include <linux/acpi.h> + #include <linux/dmi.h> + #include <linux/sched.h> /* need_resched() */ ++#include <linux/sort.h> + #include <linux/tick.h> + #include <linux/cpuidle.h> + #include <linux/cpu.h> +@@ -384,10 +385,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, + return; + } + ++static int acpi_cst_latency_cmp(const void *a, const void *b) ++{ ++ const struct acpi_processor_cx *x = a, *y = b; ++ ++ if (!(x->valid && y->valid)) ++ return 0; ++ if (x->latency > y->latency) ++ return 1; ++ if (x->latency < y->latency) ++ return -1; ++ return 0; ++} ++static void acpi_cst_latency_swap(void *a, void *b, int n) ++{ ++ struct acpi_processor_cx *x = a, *y = b; ++ u32 tmp; ++ ++ if (!(x->valid && y->valid)) ++ return; ++ tmp = x->latency; ++ x->latency = y->latency; ++ y->latency = tmp; ++} ++ + static int acpi_processor_power_verify(struct acpi_processor *pr) + { + unsigned int i; + unsigned int working = 0; ++ unsigned int last_latency = 0; ++ unsigned int last_type = 0; ++ bool buggy_latency = false; + + pr->power.timer_broadcast_on_state = INT_MAX; + +@@ -411,12 +439,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) + } + if (!cx->valid) + continue; ++ if (cx->type >= last_type && cx->latency < last_latency) ++ buggy_latency = true; ++ last_latency = cx->latency; ++ last_type = cx->type; + + lapic_timer_check_state(i, pr, cx); + tsc_check_state(cx->type); + working++; + } + ++ if (buggy_latency) { ++ pr_notice("FW issue: working around C-state latencies out of order\n"); ++ sort(&pr->power.states[1], max_cstate, ++ sizeof(struct acpi_processor_cx), ++ acpi_cst_latency_cmp, ++ acpi_cst_latency_swap); ++ } ++ + lapic_timer_propagate_broadcast(pr); + + return (working); +-- +cgit 1.2.3-1.el7 + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 7bc18cf8042c..18c2bbddf080 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -59,6 +59,7 @@ + #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e + ++#define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 + #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 + #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba + #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb +@@ -182,6 +183,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) + xhci->quirks |= XHCI_U2_DISABLE_WAKE; + ++ if (pdev->vendor == PCI_VENDOR_ID_AMD && ++ pdev->device == PCI_DEVICE_ID_AMD_RENOIR_XHCI) ++ xhci->quirks |= XHCI_BROKEN_D3COLD; ++ + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + xhci->quirks |= XHCI_LPM_SUPPORT; + xhci->quirks |= XHCI_INTEL_HOST; +@@ -539,7 +544,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) + * Systems with the TI redriver that loses port status change events + * need to have the registers polled during D3, so avoid D3cold. + */ +- if (xhci->quirks & XHCI_COMP_MODE_QUIRK) ++ if (xhci->quirks & (XHCI_COMP_MODE_QUIRK | XHCI_BROKEN_D3COLD)) + pci_d3cold_disable(pdev); + + if (xhci->quirks & XHCI_PME_STUCK_QUIRK) +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 2595a8f057c4..e417f5ce13d1 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1892,6 +1892,7 @@ struct xhci_hcd { + #define XHCI_DISABLE_SPARSE BIT_ULL(38) + #define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) + #define XHCI_NO_SOFT_RETRY BIT_ULL(40) ++#define XHCI_BROKEN_D3COLD BIT_ULL(41) + + unsigned int num_active_eps; + unsigned int limit_active_eps; +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 653660e3ba9e..36e5ec670fae 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -1904,6 +1904,9 @@ static void quirk_ryzen_xhci_d3hot(struct pci_dev *dev) + } + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e0, quirk_ryzen_xhci_d3hot); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e1, quirk_ryzen_xhci_d3hot); ++/* Renoir XHCI requires longer delay when transitioning from D0 to ++ * D3hot */ ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1639, quirk_ryzen_xhci_d3hot); + + #ifdef CONFIG_X86_IO_APIC + static int dmi_disable_ioapicreroute(const struct dmi_system_id *d) +X-Git-Url: http://git.infradead.org/nvme.git/blobdiff_plain/ebd8a93aa4f50e9e013e6aa7fe601b4ce7565c28..e21e0243e7b0f1c2a21d21f4d115f7b37175772a:/drivers/nvme/host/pci.c + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index a29b170701fc..3aa7245a505f 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2831,10 +2831,7 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + #ifdef CONFIG_ACPI + static bool nvme_acpi_storage_d3(struct pci_dev *dev) + { +- struct acpi_device *adev; +- struct pci_dev *root; +- acpi_handle handle; +- acpi_status status; ++ struct acpi_device *adev = ACPI_COMPANION(&dev->dev); + u8 val; + + /* +@@ -2842,28 +2839,9 @@ static bool nvme_acpi_storage_d3(struct pci_dev *dev) + * must use D3 to support deep platform power savings during + * suspend-to-idle. + */ +- root = pcie_find_root_port(dev); +- if (!root) +- return false; + +- adev = ACPI_COMPANION(&root->dev); + if (!adev) + return false; +- +- /* +- * The property is defined in the PXSX device for South complex ports +- * and in the PEGP device for North complex ports. +- */ +- status = acpi_get_handle(adev->handle, "PXSX", &handle); +- if (ACPI_FAILURE(status)) { +- status = acpi_get_handle(adev->handle, "PEGP", &handle); +- if (ACPI_FAILURE(status)) +- return false; +- } +- +- if (acpi_bus_get_device(handle, &adev)) +- return false; +- + if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable", + &val)) + return false; +diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c +index d260bc1f3e6e..1edb68d00b8e 100644 +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -1340,4 +1340,29 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) + return 1; + } + EXPORT_SYMBOL_GPL(acpi_dev_pm_attach); ++ ++/** ++ * acpi_storage_d3 - Check if a storage device should use D3. ++ * @dev: Device to check ++ * ++ * Returns %true if @dev should be put into D3 when the ->suspend method is ++ * called, else %false. The name of this function is somewhat misleading ++ * as it has nothing to do with storage except for the name of the ACPI ++ * property. On some platforms resume will not work if this hint is ignored. ++ * ++ */ ++bool acpi_storage_d3(struct device *dev) ++{ ++ struct acpi_device *adev = ACPI_COMPANION(dev); ++ u8 val; ++ ++ if (!adev) ++ return false; ++ if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable", ++ &val)) ++ return false; ++ return val == 1; ++} ++EXPORT_SYMBOL_GPL(acpi_storage_d3); ++ + #endif /* CONFIG_PM */ +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 3aa7245a505f..8fbc4c87a0d8 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2828,32 +2828,6 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + return 0; + } + +-#ifdef CONFIG_ACPI +-static bool nvme_acpi_storage_d3(struct pci_dev *dev) +-{ +- struct acpi_device *adev = ACPI_COMPANION(&dev->dev); +- u8 val; +- +- /* +- * Look for _DSD property specifying that the storage device on the port +- * must use D3 to support deep platform power savings during +- * suspend-to-idle. +- */ +- +- if (!adev) +- return false; +- if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable", +- &val)) +- return false; +- return val == 1; +-} +-#else +-static inline bool nvme_acpi_storage_d3(struct pci_dev *dev) +-{ +- return false; +-} +-#endif /* CONFIG_ACPI */ +- + static void nvme_async_probe(void *data, async_cookie_t cookie) + { + struct nvme_dev *dev = data; +@@ -2903,7 +2877,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + quirks |= check_vendor_combination_bug(pdev); + +- if (!noacpi && nvme_acpi_storage_d3(pdev)) { ++ if (!noacpi && acpi_storage_d3(&pdev->dev)) { + /* + * Some systems use a bios work around to ask for D3 on + * platforms that support kernel managed suspend. +diff --git a/include/linux/acpi.h b/include/linux/acpi.h +index c60745f657e9..dd0dafd21e33 100644 +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -1004,6 +1004,7 @@ int acpi_dev_resume(struct device *dev); + int acpi_subsys_runtime_suspend(struct device *dev); + int acpi_subsys_runtime_resume(struct device *dev); + int acpi_dev_pm_attach(struct device *dev, bool power_on); ++bool acpi_storage_d3(struct device *dev); + #else + static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; } + static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; } +@@ -1011,6 +1012,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) + { + return 0; + } ++static inline bool acpi_storage_d3(struct device *dev) ++{ ++ return false; ++} + #endif + + #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP) +diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c +index 1edb68d00b8e..8fd2a15bf478 100644 +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -20,6 +20,10 @@ + #include <linux/pm_runtime.h> + #include <linux/suspend.h> + ++#ifdef CONFIG_X86 ++#include <asm/cpu_device_id.h> ++#endif ++ + #include "internal.h" + + /** +@@ -1341,6 +1345,15 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) + } + EXPORT_SYMBOL_GPL(acpi_dev_pm_attach); + ++ ++#ifdef CONFIG_X86 ++static const struct x86_cpu_id storage_d3_cpu_ids[] = { ++ X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL), /* Renoir */ ++ X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */ ++ {} ++}; ++#endif ++ + /** + * acpi_storage_d3 - Check if a storage device should use D3. + * @dev: Device to check +@@ -1356,6 +1369,12 @@ bool acpi_storage_d3(struct device *dev) + struct acpi_device *adev = ACPI_COMPANION(dev); + u8 val; + ++#ifdef CONFIG_X86 ++ /* Devices requiring D3, but from before StorageD3Enable was "standardized" */ ++ if (x86_match_cpu(storage_d3_cpu_ids)) ++ return true; ++#endif ++ + if (!adev) + return false; + if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable", +From f59a905b962c34642e862b5edec35c0eda72d70d Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Wed, 5 May 2021 09:20:32 -0400 +Subject: ACPI: PM: s2idle: Add missing LPS0 functions for AMD + +These are supposedly not required for AMD platforms, +but at least some HP laptops seem to require it to +properly turn off the keyboard backlight. + +Based on a patch from Marcin Bachry <hegel666@gmail.com>. + +Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1230 +Reviewed-by: Hans de Goede <hdegoede@redhat.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +--- + drivers/acpi/x86/s2idle.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c +index 2b69536cdccba..2d7ddb8a8cb65 100644 +--- a/drivers/acpi/x86/s2idle.c ++++ b/drivers/acpi/x86/s2idle.c +@@ -42,6 +42,8 @@ static const struct acpi_device_id lps0_device_ids[] = { + + /* AMD */ + #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721" ++#define ACPI_LPS0_ENTRY_AMD 2 ++#define ACPI_LPS0_EXIT_AMD 3 + #define ACPI_LPS0_SCREEN_OFF_AMD 4 + #define ACPI_LPS0_SCREEN_ON_AMD 5 + +@@ -408,6 +410,7 @@ int acpi_s2idle_prepare_late(void) + + if (acpi_s2idle_vendor_amd()) { + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD); ++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD); + } else { + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF); + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY); +@@ -422,6 +425,7 @@ void acpi_s2idle_restore_early(void) + return; + + if (acpi_s2idle_vendor_amd()) { ++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD); + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD); + } else { + acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT); +-- +cgit 1.2.3-1.el7 + +diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c +index 2d7ddb8a8cb6..482e6b23b21a 100644 +--- a/drivers/acpi/x86/s2idle.c ++++ b/drivers/acpi/x86/s2idle.c +@@ -368,6 +368,13 @@ static int lps0_device_attach(struct acpi_device *adev, + + ACPI_FREE(out_obj); + ++ /* ++ * Some HP laptops require ACPI_LPS0_ENTRY_AMD/ACPI_LPS0_EXIT_AMD for proper ++ * S0ix, but don't set the function mask correctly. Fix that up here. ++ */ ++ if (acpi_s2idle_vendor_amd()) ++ lps0_dsm_func_mask |= (1 << ACPI_LPS0_ENTRY_AMD) | (1 << ACPI_LPS0_EXIT_AMD); ++ + acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n", + lps0_dsm_func_mask); + |