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>
21 static struct quirk_entry quirk_s2idle_bug
= {
22 .s2idle_bug_mmio
= 0xfed80380,
25 static const struct dmi_system_id fwbug_list
[] = {
27 .ident
= "L14 Gen2 AMD",
28 .driver_data
= &quirk_s2idle_bug
,
30 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
31 DMI_MATCH(DMI_PRODUCT_NAME
, "20X5"),
35 .ident
= "T14s Gen2 AMD",
36 .driver_data
= &quirk_s2idle_bug
,
38 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
39 DMI_MATCH(DMI_PRODUCT_NAME
, "20XF"),
43 .ident
= "X13 Gen2 AMD",
44 .driver_data
= &quirk_s2idle_bug
,
46 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
47 DMI_MATCH(DMI_PRODUCT_NAME
, "20XH"),
51 .ident
= "T14 Gen2 AMD",
52 .driver_data
= &quirk_s2idle_bug
,
54 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
55 DMI_MATCH(DMI_PRODUCT_NAME
, "20XK"),
59 .ident
= "T14 Gen1 AMD",
60 .driver_data
= &quirk_s2idle_bug
,
62 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
63 DMI_MATCH(DMI_PRODUCT_NAME
, "20UD"),
67 .ident
= "T14 Gen1 AMD",
68 .driver_data
= &quirk_s2idle_bug
,
70 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
71 DMI_MATCH(DMI_PRODUCT_NAME
, "20UE"),
75 .ident
= "T14s Gen1 AMD",
76 .driver_data
= &quirk_s2idle_bug
,
78 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
79 DMI_MATCH(DMI_PRODUCT_NAME
, "20UH"),
83 .ident
= "T14s Gen1 AMD",
84 .driver_data
= &quirk_s2idle_bug
,
86 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
87 DMI_MATCH(DMI_PRODUCT_NAME
, "20UJ"),
91 .ident
= "P14s Gen1 AMD",
92 .driver_data
= &quirk_s2idle_bug
,
94 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
95 DMI_MATCH(DMI_PRODUCT_NAME
, "20Y1"),
99 .ident
= "P14s Gen2 AMD",
100 .driver_data
= &quirk_s2idle_bug
,
102 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
103 DMI_MATCH(DMI_PRODUCT_NAME
, "21A0"),
107 .ident
= "P14s Gen2 AMD",
108 .driver_data
= &quirk_s2idle_bug
,
110 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
111 DMI_MATCH(DMI_PRODUCT_NAME
, "21A1"),
114 /* https://bugzilla.kernel.org/show_bug.cgi?id=218024 */
116 .ident
= "V14 G4 AMN",
117 .driver_data
= &quirk_s2idle_bug
,
119 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
120 DMI_MATCH(DMI_PRODUCT_NAME
, "82YT"),
124 .ident
= "V14 G4 AMN",
125 .driver_data
= &quirk_s2idle_bug
,
127 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
128 DMI_MATCH(DMI_PRODUCT_NAME
, "83GE"),
132 .ident
= "V15 G4 AMN",
133 .driver_data
= &quirk_s2idle_bug
,
135 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
136 DMI_MATCH(DMI_PRODUCT_NAME
, "82YU"),
140 .ident
= "V15 G4 AMN",
141 .driver_data
= &quirk_s2idle_bug
,
143 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
144 DMI_MATCH(DMI_PRODUCT_NAME
, "83CQ"),
148 .ident
= "IdeaPad 1 14AMN7",
149 .driver_data
= &quirk_s2idle_bug
,
151 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
152 DMI_MATCH(DMI_PRODUCT_NAME
, "82VF"),
156 .ident
= "IdeaPad 1 15AMN7",
157 .driver_data
= &quirk_s2idle_bug
,
159 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
160 DMI_MATCH(DMI_PRODUCT_NAME
, "82VG"),
164 .ident
= "IdeaPad 1 15AMN7",
165 .driver_data
= &quirk_s2idle_bug
,
167 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
168 DMI_MATCH(DMI_PRODUCT_NAME
, "82X5"),
172 .ident
= "IdeaPad Slim 3 14AMN8",
173 .driver_data
= &quirk_s2idle_bug
,
175 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
176 DMI_MATCH(DMI_PRODUCT_NAME
, "82XN"),
180 .ident
= "IdeaPad Slim 3 15AMN8",
181 .driver_data
= &quirk_s2idle_bug
,
183 DMI_MATCH(DMI_BOARD_VENDOR
, "LENOVO"),
184 DMI_MATCH(DMI_PRODUCT_NAME
, "82XQ"),
187 /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */
189 .ident
= "HP Laptop 15s-eq2xxx",
190 .driver_data
= &quirk_s2idle_bug
,
192 DMI_MATCH(DMI_SYS_VENDOR
, "HP"),
193 DMI_MATCH(DMI_PRODUCT_NAME
, "HP Laptop 15s-eq2xxx"),
200 * Laptops that run a SMI handler during the D3->D0 transition that occurs
201 * specifically when exiting suspend to idle which can cause
202 * large delays during resume when the IOMMU translation layer is enabled (the default
203 * behavior) for NVME devices:
205 * To avoid this firmware problem, skip the SMI handler on these machines before the
206 * D0 transition occurs.
208 static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio
)
213 if (!request_mem_region_muxed(s2idle_bug_mmio
, 1, "amd_pmc_pm80"))
216 addr
= ioremap(s2idle_bug_mmio
, 1);
218 goto cleanup_resource
;
221 iowrite8(val
& ~BIT(0), addr
);
225 release_mem_region(s2idle_bug_mmio
, 1);
228 void amd_pmc_process_restore_quirks(struct amd_pmc_dev
*dev
)
230 if (dev
->quirks
&& dev
->quirks
->s2idle_bug_mmio
)
231 amd_pmc_skip_nvme_smi_handler(dev
->quirks
->s2idle_bug_mmio
);
234 void amd_pmc_quirks_init(struct amd_pmc_dev
*dev
)
236 const struct dmi_system_id
*dmi_id
;
238 dmi_id
= dmi_first_match(fwbug_list
);
241 dev
->quirks
= dmi_id
->driver_data
;
242 if (dev
->quirks
->s2idle_bug_mmio
)
243 pr_info("Using s2idle quirk to avoid %s platform firmware bug\n",