powercap: intel_rapl_tpmi: Enable PMU support
[linux-block.git] / drivers / platform / x86 / amd / pmc / pmc-quirks.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * AMD SoC Power Management Controller Driver Quirks
4  *
5  * Copyright (c) 2023, Advanced Micro Devices, Inc.
6  * All Rights Reserved.
7  *
8  * Author: Mario Limonciello <mario.limonciello@amd.com>
9  */
10
11 #include <linux/dmi.h>
12 #include <linux/io.h>
13 #include <linux/ioport.h>
14
15 #include "pmc.h"
16
17 struct quirk_entry {
18         u32 s2idle_bug_mmio;
19         bool spurious_8042;
20 };
21
22 static struct quirk_entry quirk_s2idle_bug = {
23         .s2idle_bug_mmio = 0xfed80380,
24 };
25
26 static struct quirk_entry quirk_spurious_8042 = {
27         .spurious_8042 = true,
28 };
29
30 static const struct dmi_system_id fwbug_list[] = {
31         {
32                 .ident = "L14 Gen2 AMD",
33                 .driver_data = &quirk_s2idle_bug,
34                 .matches = {
35                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
36                         DMI_MATCH(DMI_PRODUCT_NAME, "20X5"),
37                 }
38         },
39         {
40                 .ident = "T14s Gen2 AMD",
41                 .driver_data = &quirk_s2idle_bug,
42                 .matches = {
43                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
44                         DMI_MATCH(DMI_PRODUCT_NAME, "20XF"),
45                 }
46         },
47         {
48                 .ident = "X13 Gen2 AMD",
49                 .driver_data = &quirk_s2idle_bug,
50                 .matches = {
51                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
52                         DMI_MATCH(DMI_PRODUCT_NAME, "20XH"),
53                 }
54         },
55         {
56                 .ident = "T14 Gen2 AMD",
57                 .driver_data = &quirk_s2idle_bug,
58                 .matches = {
59                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
60                         DMI_MATCH(DMI_PRODUCT_NAME, "20XK"),
61                 }
62         },
63         {
64                 .ident = "T14 Gen1 AMD",
65                 .driver_data = &quirk_s2idle_bug,
66                 .matches = {
67                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
68                         DMI_MATCH(DMI_PRODUCT_NAME, "20UD"),
69                 }
70         },
71         {
72                 .ident = "T14 Gen1 AMD",
73                 .driver_data = &quirk_s2idle_bug,
74                 .matches = {
75                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
76                         DMI_MATCH(DMI_PRODUCT_NAME, "20UE"),
77                 }
78         },
79         {
80                 .ident = "T14s Gen1 AMD",
81                 .driver_data = &quirk_s2idle_bug,
82                 .matches = {
83                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
84                         DMI_MATCH(DMI_PRODUCT_NAME, "20UH"),
85                 }
86         },
87         {
88                 .ident = "T14s Gen1 AMD",
89                 .driver_data = &quirk_s2idle_bug,
90                 .matches = {
91                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
92                         DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"),
93                 }
94         },
95         {
96                 .ident = "P14s Gen1 AMD",
97                 .driver_data = &quirk_s2idle_bug,
98                 .matches = {
99                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
100                         DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"),
101                 }
102         },
103         {
104                 .ident = "P14s Gen2 AMD",
105                 .driver_data = &quirk_s2idle_bug,
106                 .matches = {
107                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
108                         DMI_MATCH(DMI_PRODUCT_NAME, "21A0"),
109                 }
110         },
111         {
112                 .ident = "P14s Gen2 AMD",
113                 .driver_data = &quirk_s2idle_bug,
114                 .matches = {
115                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
116                         DMI_MATCH(DMI_PRODUCT_NAME, "21A1"),
117                 }
118         },
119         /* https://bugzilla.kernel.org/show_bug.cgi?id=218024 */
120         {
121                 .ident = "V14 G4 AMN",
122                 .driver_data = &quirk_s2idle_bug,
123                 .matches = {
124                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
125                         DMI_MATCH(DMI_PRODUCT_NAME, "82YT"),
126                 }
127         },
128         {
129                 .ident = "V14 G4 AMN",
130                 .driver_data = &quirk_s2idle_bug,
131                 .matches = {
132                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
133                         DMI_MATCH(DMI_PRODUCT_NAME, "83GE"),
134                 }
135         },
136         {
137                 .ident = "V15 G4 AMN",
138                 .driver_data = &quirk_s2idle_bug,
139                 .matches = {
140                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
141                         DMI_MATCH(DMI_PRODUCT_NAME, "82YU"),
142                 }
143         },
144         {
145                 .ident = "V15 G4 AMN",
146                 .driver_data = &quirk_s2idle_bug,
147                 .matches = {
148                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
149                         DMI_MATCH(DMI_PRODUCT_NAME, "83CQ"),
150                 }
151         },
152         {
153                 .ident = "IdeaPad 1 14AMN7",
154                 .driver_data = &quirk_s2idle_bug,
155                 .matches = {
156                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
157                         DMI_MATCH(DMI_PRODUCT_NAME, "82VF"),
158                 }
159         },
160         {
161                 .ident = "IdeaPad 1 15AMN7",
162                 .driver_data = &quirk_s2idle_bug,
163                 .matches = {
164                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
165                         DMI_MATCH(DMI_PRODUCT_NAME, "82VG"),
166                 }
167         },
168         {
169                 .ident = "IdeaPad 1 15AMN7",
170                 .driver_data = &quirk_s2idle_bug,
171                 .matches = {
172                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
173                         DMI_MATCH(DMI_PRODUCT_NAME, "82X5"),
174                 }
175         },
176         {
177                 .ident = "IdeaPad Slim 3 14AMN8",
178                 .driver_data = &quirk_s2idle_bug,
179                 .matches = {
180                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
181                         DMI_MATCH(DMI_PRODUCT_NAME, "82XN"),
182                 }
183         },
184         {
185                 .ident = "IdeaPad Slim 3 15AMN8",
186                 .driver_data = &quirk_s2idle_bug,
187                 .matches = {
188                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
189                         DMI_MATCH(DMI_PRODUCT_NAME, "82XQ"),
190                 }
191         },
192         /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */
193         {
194                 .ident = "HP Laptop 15s-eq2xxx",
195                 .driver_data = &quirk_s2idle_bug,
196                 .matches = {
197                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
198                         DMI_MATCH(DMI_PRODUCT_NAME, "HP Laptop 15s-eq2xxx"),
199                 }
200         },
201         /* https://community.frame.work/t/tracking-framework-amd-ryzen-7040-series-lid-wakeup-behavior-feedback/39128 */
202         {
203                 .ident = "Framework Laptop 13 (Phoenix)",
204                 .driver_data = &quirk_spurious_8042,
205                 .matches = {
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"),
209                 }
210         },
211         {}
212 };
213
214 /*
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:
219  *
220  * To avoid this firmware problem, skip the SMI handler on these machines before the
221  * D0 transition occurs.
222  */
223 static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio)
224 {
225         void __iomem *addr;
226         u8 val;
227
228         if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"))
229                 return;
230
231         addr = ioremap(s2idle_bug_mmio, 1);
232         if (!addr)
233                 goto cleanup_resource;
234
235         val = ioread8(addr);
236         iowrite8(val & ~BIT(0), addr);
237
238         iounmap(addr);
239 cleanup_resource:
240         release_mem_region(s2idle_bug_mmio, 1);
241 }
242
243 void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev)
244 {
245         if (dev->quirks && dev->quirks->s2idle_bug_mmio)
246                 amd_pmc_skip_nvme_smi_handler(dev->quirks->s2idle_bug_mmio);
247 }
248
249 void amd_pmc_quirks_init(struct amd_pmc_dev *dev)
250 {
251         const struct dmi_system_id *dmi_id;
252
253         if (dev->cpu_id == AMD_CPU_ID_CZN)
254                 dev->disable_8042_wakeup = true;
255
256         dmi_id = dmi_first_match(fwbug_list);
257         if (!dmi_id)
258                 return;
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",
262                         dmi_id->ident);
263         if (dev->quirks->spurious_8042)
264                 dev->disable_8042_wakeup = true;
265 }