xref: /openbmc/linux/drivers/platform/x86/amd/pmc/pmc-quirks.c (revision c845428b7a9157523103100806bc8130d64769c8)
192c2fb8fSShyam Sundar S K // SPDX-License-Identifier: GPL-2.0-or-later
292c2fb8fSShyam Sundar S K /*
392c2fb8fSShyam Sundar S K  * AMD SoC Power Management Controller Driver Quirks
492c2fb8fSShyam Sundar S K  *
592c2fb8fSShyam Sundar S K  * Copyright (c) 2023, Advanced Micro Devices, Inc.
692c2fb8fSShyam Sundar S K  * All Rights Reserved.
792c2fb8fSShyam Sundar S K  *
892c2fb8fSShyam Sundar S K  * Author: Mario Limonciello <mario.limonciello@amd.com>
992c2fb8fSShyam Sundar S K  */
1092c2fb8fSShyam Sundar S K 
1192c2fb8fSShyam Sundar S K #include <linux/dmi.h>
1292c2fb8fSShyam Sundar S K #include <linux/io.h>
1392c2fb8fSShyam Sundar S K #include <linux/ioport.h>
1492c2fb8fSShyam Sundar S K 
1592c2fb8fSShyam Sundar S K #include "pmc.h"
1692c2fb8fSShyam Sundar S K 
1792c2fb8fSShyam Sundar S K struct quirk_entry {
1892c2fb8fSShyam Sundar S K 	u32 s2idle_bug_mmio;
191339559bSMario Limonciello 	bool spurious_8042;
2092c2fb8fSShyam Sundar S K };
2192c2fb8fSShyam Sundar S K 
2292c2fb8fSShyam Sundar S K static struct quirk_entry quirk_s2idle_bug = {
2392c2fb8fSShyam Sundar S K 	.s2idle_bug_mmio = 0xfed80380,
2492c2fb8fSShyam Sundar S K };
2592c2fb8fSShyam Sundar S K 
261339559bSMario Limonciello static struct quirk_entry quirk_spurious_8042 = {
271339559bSMario Limonciello 	.spurious_8042 = true,
281339559bSMario Limonciello };
291339559bSMario Limonciello 
3092c2fb8fSShyam Sundar S K static const struct dmi_system_id fwbug_list[] = {
3192c2fb8fSShyam Sundar S K 	{
3292c2fb8fSShyam Sundar S K 		.ident = "L14 Gen2 AMD",
3392c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
3492c2fb8fSShyam Sundar S K 		.matches = {
3592c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
3692c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20X5"),
3792c2fb8fSShyam Sundar S K 		}
3892c2fb8fSShyam Sundar S K 	},
3992c2fb8fSShyam Sundar S K 	{
4092c2fb8fSShyam Sundar S K 		.ident = "T14s Gen2 AMD",
4192c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
4292c2fb8fSShyam Sundar S K 		.matches = {
4392c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
4492c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20XF"),
4592c2fb8fSShyam Sundar S K 		}
4692c2fb8fSShyam Sundar S K 	},
4792c2fb8fSShyam Sundar S K 	{
4892c2fb8fSShyam Sundar S K 		.ident = "X13 Gen2 AMD",
4992c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
5092c2fb8fSShyam Sundar S K 		.matches = {
5192c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
5292c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20XH"),
5392c2fb8fSShyam Sundar S K 		}
5492c2fb8fSShyam Sundar S K 	},
5592c2fb8fSShyam Sundar S K 	{
5692c2fb8fSShyam Sundar S K 		.ident = "T14 Gen2 AMD",
5792c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
5892c2fb8fSShyam Sundar S K 		.matches = {
5992c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
6092c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20XK"),
6192c2fb8fSShyam Sundar S K 		}
6292c2fb8fSShyam Sundar S K 	},
6392c2fb8fSShyam Sundar S K 	{
6492c2fb8fSShyam Sundar S K 		.ident = "T14 Gen1 AMD",
6592c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
6692c2fb8fSShyam Sundar S K 		.matches = {
6792c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
6892c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20UD"),
6992c2fb8fSShyam Sundar S K 		}
7092c2fb8fSShyam Sundar S K 	},
7192c2fb8fSShyam Sundar S K 	{
7292c2fb8fSShyam Sundar S K 		.ident = "T14 Gen1 AMD",
7392c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
7492c2fb8fSShyam Sundar S K 		.matches = {
7592c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
7692c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20UE"),
7792c2fb8fSShyam Sundar S K 		}
7892c2fb8fSShyam Sundar S K 	},
7992c2fb8fSShyam Sundar S K 	{
8092c2fb8fSShyam Sundar S K 		.ident = "T14s Gen1 AMD",
8192c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
8292c2fb8fSShyam Sundar S K 		.matches = {
8392c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
8492c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20UH"),
8592c2fb8fSShyam Sundar S K 		}
8692c2fb8fSShyam Sundar S K 	},
8792c2fb8fSShyam Sundar S K 	{
8892c2fb8fSShyam Sundar S K 		.ident = "T14s Gen1 AMD",
8992c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
9092c2fb8fSShyam Sundar S K 		.matches = {
9192c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
9292c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"),
9392c2fb8fSShyam Sundar S K 		}
9492c2fb8fSShyam Sundar S K 	},
9592c2fb8fSShyam Sundar S K 	{
9692c2fb8fSShyam Sundar S K 		.ident = "P14s Gen1 AMD",
9792c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
9892c2fb8fSShyam Sundar S K 		.matches = {
9992c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
10092c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"),
10192c2fb8fSShyam Sundar S K 		}
10292c2fb8fSShyam Sundar S K 	},
10392c2fb8fSShyam Sundar S K 	{
10492c2fb8fSShyam Sundar S K 		.ident = "P14s Gen2 AMD",
10592c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
10692c2fb8fSShyam Sundar S K 		.matches = {
10792c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
10892c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "21A0"),
10992c2fb8fSShyam Sundar S K 		}
11092c2fb8fSShyam Sundar S K 	},
11192c2fb8fSShyam Sundar S K 	{
11292c2fb8fSShyam Sundar S K 		.ident = "P14s Gen2 AMD",
11392c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
11492c2fb8fSShyam Sundar S K 		.matches = {
11592c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
11692c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "21A1"),
11792c2fb8fSShyam Sundar S K 		}
11892c2fb8fSShyam Sundar S K 	},
1193bde7ec1SDavid Lazar 	/* https://bugzilla.kernel.org/show_bug.cgi?id=218024 */
1203bde7ec1SDavid Lazar 	{
1213bde7ec1SDavid Lazar 		.ident = "V14 G4 AMN",
1223bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1233bde7ec1SDavid Lazar 		.matches = {
1243bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1253bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "82YT"),
1263bde7ec1SDavid Lazar 		}
1273bde7ec1SDavid Lazar 	},
1283bde7ec1SDavid Lazar 	{
1293bde7ec1SDavid Lazar 		.ident = "V14 G4 AMN",
1303bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1313bde7ec1SDavid Lazar 		.matches = {
1323bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1333bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "83GE"),
1343bde7ec1SDavid Lazar 		}
1353bde7ec1SDavid Lazar 	},
1363bde7ec1SDavid Lazar 	{
1373bde7ec1SDavid Lazar 		.ident = "V15 G4 AMN",
1383bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1393bde7ec1SDavid Lazar 		.matches = {
1403bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1413bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "82YU"),
1423bde7ec1SDavid Lazar 		}
1433bde7ec1SDavid Lazar 	},
1443bde7ec1SDavid Lazar 	{
1453bde7ec1SDavid Lazar 		.ident = "V15 G4 AMN",
1463bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1473bde7ec1SDavid Lazar 		.matches = {
1483bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1493bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "83CQ"),
1503bde7ec1SDavid Lazar 		}
1513bde7ec1SDavid Lazar 	},
1523bde7ec1SDavid Lazar 	{
1533bde7ec1SDavid Lazar 		.ident = "IdeaPad 1 14AMN7",
1543bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1553bde7ec1SDavid Lazar 		.matches = {
1563bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1573bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "82VF"),
1583bde7ec1SDavid Lazar 		}
1593bde7ec1SDavid Lazar 	},
1603bde7ec1SDavid Lazar 	{
1613bde7ec1SDavid Lazar 		.ident = "IdeaPad 1 15AMN7",
1623bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1633bde7ec1SDavid Lazar 		.matches = {
1643bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1653bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "82VG"),
1663bde7ec1SDavid Lazar 		}
1673bde7ec1SDavid Lazar 	},
1683bde7ec1SDavid Lazar 	{
1693bde7ec1SDavid Lazar 		.ident = "IdeaPad 1 15AMN7",
1703bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1713bde7ec1SDavid Lazar 		.matches = {
1723bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1733bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "82X5"),
1743bde7ec1SDavid Lazar 		}
1753bde7ec1SDavid Lazar 	},
1763bde7ec1SDavid Lazar 	{
1773bde7ec1SDavid Lazar 		.ident = "IdeaPad Slim 3 14AMN8",
1783bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1793bde7ec1SDavid Lazar 		.matches = {
1803bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1813bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "82XN"),
1823bde7ec1SDavid Lazar 		}
1833bde7ec1SDavid Lazar 	},
1843bde7ec1SDavid Lazar 	{
1853bde7ec1SDavid Lazar 		.ident = "IdeaPad Slim 3 15AMN8",
1863bde7ec1SDavid Lazar 		.driver_data = &quirk_s2idle_bug,
1873bde7ec1SDavid Lazar 		.matches = {
1883bde7ec1SDavid Lazar 			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1893bde7ec1SDavid Lazar 			DMI_MATCH(DMI_PRODUCT_NAME, "82XQ"),
1903bde7ec1SDavid Lazar 		}
1913bde7ec1SDavid Lazar 	},
19292c2fb8fSShyam Sundar S K 	/* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */
19392c2fb8fSShyam Sundar S K 	{
19492c2fb8fSShyam Sundar S K 		.ident = "HP Laptop 15s-eq2xxx",
19592c2fb8fSShyam Sundar S K 		.driver_data = &quirk_s2idle_bug,
19692c2fb8fSShyam Sundar S K 		.matches = {
19792c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
19892c2fb8fSShyam Sundar S K 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Laptop 15s-eq2xxx"),
19992c2fb8fSShyam Sundar S K 		}
20092c2fb8fSShyam Sundar S K 	},
2011339559bSMario Limonciello 	/* https://community.frame.work/t/tracking-framework-amd-ryzen-7040-series-lid-wakeup-behavior-feedback/39128 */
2021339559bSMario Limonciello 	{
2031339559bSMario Limonciello 		.ident = "Framework Laptop 13 (Phoenix)",
2041339559bSMario Limonciello 		.driver_data = &quirk_spurious_8042,
2051339559bSMario Limonciello 		.matches = {
2061339559bSMario Limonciello 			DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
2071339559bSMario Limonciello 			DMI_MATCH(DMI_PRODUCT_NAME, "Laptop 13 (AMD Ryzen 7040Series)"),
2081339559bSMario Limonciello 			DMI_MATCH(DMI_BIOS_VERSION, "03.03"),
2091339559bSMario Limonciello 		}
2101339559bSMario Limonciello 	},
211*d7cc1d72SMario Limonciello 	{
212*d7cc1d72SMario Limonciello 		.ident = "Framework Laptop 13 (Phoenix)",
213*d7cc1d72SMario Limonciello 		.driver_data = &quirk_spurious_8042,
214*d7cc1d72SMario Limonciello 		.matches = {
215*d7cc1d72SMario Limonciello 			DMI_MATCH(DMI_SYS_VENDOR, "Framework"),
216*d7cc1d72SMario Limonciello 			DMI_MATCH(DMI_PRODUCT_NAME, "Laptop 13 (AMD Ryzen 7040Series)"),
217*d7cc1d72SMario Limonciello 			DMI_MATCH(DMI_BIOS_VERSION, "03.05"),
218*d7cc1d72SMario Limonciello 		}
219*d7cc1d72SMario Limonciello 	},
22092c2fb8fSShyam Sundar S K 	{}
22192c2fb8fSShyam Sundar S K };
22292c2fb8fSShyam Sundar S K 
22392c2fb8fSShyam Sundar S K /*
22492c2fb8fSShyam Sundar S K  * Laptops that run a SMI handler during the D3->D0 transition that occurs
22592c2fb8fSShyam Sundar S K  * specifically when exiting suspend to idle which can cause
22692c2fb8fSShyam Sundar S K  * large delays during resume when the IOMMU translation layer is enabled (the default
22792c2fb8fSShyam Sundar S K  * behavior) for NVME devices:
22892c2fb8fSShyam Sundar S K  *
22992c2fb8fSShyam Sundar S K  * To avoid this firmware problem, skip the SMI handler on these machines before the
23092c2fb8fSShyam Sundar S K  * D0 transition occurs.
23192c2fb8fSShyam Sundar S K  */
amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio)23292c2fb8fSShyam Sundar S K static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio)
23392c2fb8fSShyam Sundar S K {
23492c2fb8fSShyam Sundar S K 	void __iomem *addr;
23592c2fb8fSShyam Sundar S K 	u8 val;
23692c2fb8fSShyam Sundar S K 
23792c2fb8fSShyam Sundar S K 	if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"))
23892c2fb8fSShyam Sundar S K 		return;
23992c2fb8fSShyam Sundar S K 
24092c2fb8fSShyam Sundar S K 	addr = ioremap(s2idle_bug_mmio, 1);
24192c2fb8fSShyam Sundar S K 	if (!addr)
24292c2fb8fSShyam Sundar S K 		goto cleanup_resource;
24392c2fb8fSShyam Sundar S K 
24492c2fb8fSShyam Sundar S K 	val = ioread8(addr);
24592c2fb8fSShyam Sundar S K 	iowrite8(val & ~BIT(0), addr);
24692c2fb8fSShyam Sundar S K 
24792c2fb8fSShyam Sundar S K 	iounmap(addr);
24892c2fb8fSShyam Sundar S K cleanup_resource:
24992c2fb8fSShyam Sundar S K 	release_mem_region(s2idle_bug_mmio, 1);
25092c2fb8fSShyam Sundar S K }
25192c2fb8fSShyam Sundar S K 
amd_pmc_process_restore_quirks(struct amd_pmc_dev * dev)25292c2fb8fSShyam Sundar S K void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev)
25392c2fb8fSShyam Sundar S K {
25492c2fb8fSShyam Sundar S K 	if (dev->quirks && dev->quirks->s2idle_bug_mmio)
25592c2fb8fSShyam Sundar S K 		amd_pmc_skip_nvme_smi_handler(dev->quirks->s2idle_bug_mmio);
25692c2fb8fSShyam Sundar S K }
25792c2fb8fSShyam Sundar S K 
amd_pmc_quirks_init(struct amd_pmc_dev * dev)25892c2fb8fSShyam Sundar S K void amd_pmc_quirks_init(struct amd_pmc_dev *dev)
25992c2fb8fSShyam Sundar S K {
26092c2fb8fSShyam Sundar S K 	const struct dmi_system_id *dmi_id;
26192c2fb8fSShyam Sundar S K 
2625b235bbcSMario Limonciello 	if (dev->cpu_id == AMD_CPU_ID_CZN)
2635b235bbcSMario Limonciello 		dev->disable_8042_wakeup = true;
2645b235bbcSMario Limonciello 
26592c2fb8fSShyam Sundar S K 	dmi_id = dmi_first_match(fwbug_list);
26692c2fb8fSShyam Sundar S K 	if (!dmi_id)
26792c2fb8fSShyam Sundar S K 		return;
26892c2fb8fSShyam Sundar S K 	dev->quirks = dmi_id->driver_data;
26992c2fb8fSShyam Sundar S K 	if (dev->quirks->s2idle_bug_mmio)
27092c2fb8fSShyam Sundar S K 		pr_info("Using s2idle quirk to avoid %s platform firmware bug\n",
27192c2fb8fSShyam Sundar S K 			dmi_id->ident);
2721339559bSMario Limonciello 	if (dev->quirks->spurious_8042)
2731339559bSMario Limonciello 		dev->disable_8042_wakeup = true;
27492c2fb8fSShyam Sundar S K }
275