1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * AMD SoC Power Management Controller Driver Quirks
5 * Copyright (c) 2023, Advanced Micro Devices, Inc.
8 * Author: Mario Limonciello <mario.limonciello@amd.com>
11 #include <linux/dmi.h>
13 #include <linux/ioport.h>
22 static struct quirk_entry quirk_s2idle_bug = {
23 .s2idle_bug_mmio = 0xfed80380,
26 static struct quirk_entry quirk_spurious_8042 = {
27 .spurious_8042 = true,
30 static const struct dmi_system_id fwbug_list[] = {
32 .ident = "L14 Gen2 AMD",
33 .driver_data = &quirk_s2idle_bug,
35 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
36 DMI_MATCH(DMI_PRODUCT_NAME, "20X5"),
40 .ident = "T14s Gen2 AMD",
41 .driver_data = &quirk_s2idle_bug,
43 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
44 DMI_MATCH(DMI_PRODUCT_NAME, "20XF"),
48 .ident = "X13 Gen2 AMD",
49 .driver_data = &quirk_s2idle_bug,
51 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
52 DMI_MATCH(DMI_PRODUCT_NAME, "20XH"),
56 .ident = "T14 Gen2 AMD",
57 .driver_data = &quirk_s2idle_bug,
59 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
60 DMI_MATCH(DMI_PRODUCT_NAME, "20XK"),
64 .ident = "T14 Gen1 AMD",
65 .driver_data = &quirk_s2idle_bug,
67 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
68 DMI_MATCH(DMI_PRODUCT_NAME, "20UD"),
72 .ident = "T14 Gen1 AMD",
73 .driver_data = &quirk_s2idle_bug,
75 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
76 DMI_MATCH(DMI_PRODUCT_NAME, "20UE"),
80 .ident = "T14s Gen1 AMD",
81 .driver_data = &quirk_s2idle_bug,
83 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
84 DMI_MATCH(DMI_PRODUCT_NAME, "20UH"),
88 .ident = "T14s Gen1 AMD",
89 .driver_data = &quirk_s2idle_bug,
91 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
92 DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"),
96 .ident = "P14s Gen1 AMD",
97 .driver_data = &quirk_s2idle_bug,
99 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
100 DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"),
104 .ident = "P14s Gen2 AMD",
105 .driver_data = &quirk_s2idle_bug,
107 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
108 DMI_MATCH(DMI_PRODUCT_NAME, "21A0"),
112 .ident = "P14s Gen2 AMD",
113 .driver_data = &quirk_s2idle_bug,
115 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
116 DMI_MATCH(DMI_PRODUCT_NAME, "21A1"),
119 /* https://bugzilla.kernel.org/show_bug.cgi?id=218024 */
121 .ident = "V14 G4 AMN",
122 .driver_data = &quirk_s2idle_bug,
124 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
125 DMI_MATCH(DMI_PRODUCT_NAME, "82YT"),
129 .ident = "V14 G4 AMN",
130 .driver_data = &quirk_s2idle_bug,
132 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
133 DMI_MATCH(DMI_PRODUCT_NAME, "83GE"),
137 .ident = "V15 G4 AMN",
138 .driver_data = &quirk_s2idle_bug,
140 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
141 DMI_MATCH(DMI_PRODUCT_NAME, "82YU"),
145 .ident = "V15 G4 AMN",
146 .driver_data = &quirk_s2idle_bug,
148 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
149 DMI_MATCH(DMI_PRODUCT_NAME, "83CQ"),
153 .ident = "IdeaPad 1 14AMN7",
154 .driver_data = &quirk_s2idle_bug,
156 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
157 DMI_MATCH(DMI_PRODUCT_NAME, "82VF"),
161 .ident = "IdeaPad 1 15AMN7",
162 .driver_data = &quirk_s2idle_bug,
164 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
165 DMI_MATCH(DMI_PRODUCT_NAME, "82VG"),
169 .ident = "IdeaPad 1 15AMN7",
170 .driver_data = &quirk_s2idle_bug,
172 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
173 DMI_MATCH(DMI_PRODUCT_NAME, "82X5"),
177 .ident = "IdeaPad Slim 3 14AMN8",
178 .driver_data = &quirk_s2idle_bug,
180 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
181 DMI_MATCH(DMI_PRODUCT_NAME, "82XN"),
185 .ident = "IdeaPad Slim 3 15AMN8",
186 .driver_data = &quirk_s2idle_bug,
188 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
189 DMI_MATCH(DMI_PRODUCT_NAME, "82XQ"),
192 /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */
194 .ident = "HP Laptop 15s-eq2xxx",
195 .driver_data = &quirk_s2idle_bug,
197 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
198 DMI_MATCH(DMI_PRODUCT_NAME, "HP Laptop 15s-eq2xxx"),
201 /* https://community.frame.work/t/tracking-framework-amd-ryzen-7040-series-lid-wakeup-behavior-feedback/39128 */
203 .ident = "Framework Laptop 13 (Phoenix)",
204 .driver_data = &quirk_spurious_8042,
206 DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
207 DMI_MATCH(DMI_PRODUCT_NAME, "Laptop 13 (AMD Ryzen 7040Series)"),
208 DMI_MATCH(DMI_BIOS_VERSION, "03.03"),
215 * Laptops that run a SMI handler during the D3->D0 transition that occurs
216 * specifically when exiting suspend to idle which can cause
217 * large delays during resume when the IOMMU translation layer is enabled (the default
218 * behavior) for NVME devices:
220 * To avoid this firmware problem, skip the SMI handler on these machines before the
221 * D0 transition occurs.
223 static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio)
228 if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"))
231 addr = ioremap(s2idle_bug_mmio, 1);
233 goto cleanup_resource;
236 iowrite8(val & ~BIT(0), addr);
240 release_mem_region(s2idle_bug_mmio, 1);
243 void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev)
245 if (dev->quirks && dev->quirks->s2idle_bug_mmio)
246 amd_pmc_skip_nvme_smi_handler(dev->quirks->s2idle_bug_mmio);
249 void amd_pmc_quirks_init(struct amd_pmc_dev *dev)
251 const struct dmi_system_id *dmi_id;
253 if (dev->cpu_id == AMD_CPU_ID_CZN)
254 dev->disable_8042_wakeup = true;
256 dmi_id = dmi_first_match(fwbug_list);
259 dev->quirks = dmi_id->driver_data;
260 if (dev->quirks->s2idle_bug_mmio)
261 pr_info("Using s2idle quirk to avoid %s platform firmware bug\n",
263 if (dev->quirks->spurious_8042)
264 dev->disable_8042_wakeup = true;