275 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * AMD SoC Power Management Controller Driver Quirks4 *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 17struct quirk_entry {18 u32 s2idle_bug_mmio;19 bool spurious_8042;20};21 22static struct quirk_entry quirk_s2idle_bug = {23 .s2idle_bug_mmio = 0xfed80380,24};25 26static struct quirk_entry quirk_spurious_8042 = {27 .spurious_8042 = true,28};29 30static 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 .ident = "Framework Laptop 13 (Phoenix)",213 .driver_data = &quirk_spurious_8042,214 .matches = {215 DMI_MATCH(DMI_SYS_VENDOR, "Framework"),216 DMI_MATCH(DMI_PRODUCT_NAME, "Laptop 13 (AMD Ryzen 7040Series)"),217 DMI_MATCH(DMI_BIOS_VERSION, "03.05"),218 }219 },220 {}221};222 223/*224 * Laptops that run a SMI handler during the D3->D0 transition that occurs225 * specifically when exiting suspend to idle which can cause226 * large delays during resume when the IOMMU translation layer is enabled (the default227 * behavior) for NVME devices:228 *229 * To avoid this firmware problem, skip the SMI handler on these machines before the230 * D0 transition occurs.231 */232static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio)233{234 void __iomem *addr;235 u8 val;236 237 if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"))238 return;239 240 addr = ioremap(s2idle_bug_mmio, 1);241 if (!addr)242 goto cleanup_resource;243 244 val = ioread8(addr);245 iowrite8(val & ~BIT(0), addr);246 247 iounmap(addr);248cleanup_resource:249 release_mem_region(s2idle_bug_mmio, 1);250}251 252void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev)253{254 if (dev->quirks && dev->quirks->s2idle_bug_mmio)255 amd_pmc_skip_nvme_smi_handler(dev->quirks->s2idle_bug_mmio);256}257 258void amd_pmc_quirks_init(struct amd_pmc_dev *dev)259{260 const struct dmi_system_id *dmi_id;261 262 if (dev->cpu_id == AMD_CPU_ID_CZN)263 dev->disable_8042_wakeup = true;264 265 dmi_id = dmi_first_match(fwbug_list);266 if (!dmi_id)267 return;268 dev->quirks = dmi_id->driver_data;269 if (dev->quirks->s2idle_bug_mmio)270 pr_info("Using s2idle quirk to avoid %s platform firmware bug\n",271 dmi_id->ident);272 if (dev->quirks->spurious_8042)273 dev->disable_8042_wakeup = true;274}275