From e8ef8dd28c4c4b86cd3010ff42c79582f766862e Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 10 Jul 2023 13:39:33 -0500 Subject: platform/x86: Move s2idle quirk from thinkpad-acpi to amd-pmc It turns out that some-non Lenovo systems can benefit from the quirk introduced for Lenovo systems in commit 455cd867b85b5 ("platform/x86: thinkpad_acpi: Add a s2idle resume quirk for a number of laptops"). So move this quirk into running from the amd-pmc driver instead. No intended functional changes. Signed-off-by: Mario Limonciello Link: https://lore.kernel.org/r/20230710183934.17315-2-mario.limonciello@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/Makefile | 2 +- drivers/platform/x86/amd/pmc-quirks.c | 167 ++++++++++++++++++++++++++++++++++ drivers/platform/x86/amd/pmc.c | 29 ++---- drivers/platform/x86/amd/pmc.h | 44 +++++++++ 4 files changed, 218 insertions(+), 24 deletions(-) create mode 100644 drivers/platform/x86/amd/pmc-quirks.c create mode 100644 drivers/platform/x86/amd/pmc.h (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile index 2c229198e24c..65732f0a3913 100644 --- a/drivers/platform/x86/amd/Makefile +++ b/drivers/platform/x86/amd/Makefile @@ -4,7 +4,7 @@ # AMD x86 Platform-Specific Drivers # -amd-pmc-y := pmc.o +amd-pmc-y := pmc.o pmc-quirks.o obj-$(CONFIG_AMD_PMC) += amd-pmc.o amd_hsmp-y := hsmp.o obj-$(CONFIG_AMD_HSMP) += amd_hsmp.o diff --git a/drivers/platform/x86/amd/pmc-quirks.c b/drivers/platform/x86/amd/pmc-quirks.c new file mode 100644 index 000000000000..21a977004db8 --- /dev/null +++ b/drivers/platform/x86/amd/pmc-quirks.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD SoC Power Management Controller Driver Quirks + * + * Copyright (c) 2023, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Author: Mario Limonciello + */ + +#include +#include +#include +#include + +#include "pmc.h" + +struct quirk_entry { + u32 s2idle_bug_mmio; +}; + +static struct quirk_entry quirk_s2idle_bug = { + .s2idle_bug_mmio = 0xfed80380, +}; + +static const struct dmi_system_id fwbug_list[] = { + { + .ident = "L14 Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20X5"), + } + }, + { + .ident = "T14s Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20XF"), + } + }, + { + .ident = "X13 Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20XH"), + } + }, + { + .ident = "T14 Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20XK"), + } + }, + { + .ident = "T14 Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UD"), + } + }, + { + .ident = "T14 Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UE"), + } + }, + { + .ident = "T14s Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UH"), + } + }, + { + .ident = "T14s Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"), + } + }, + { + .ident = "P14s Gen1 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"), + } + }, + { + .ident = "P14s Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21A0"), + } + }, + { + .ident = "P14s Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), + } + }, + {} +}; + +/* + * Laptops that run a SMI handler during the D3->D0 transition that occurs + * specifically when exiting suspend to idle which can cause + * large delays during resume when the IOMMU translation layer is enabled (the default + * behavior) for NVME devices: + * + * To avoid this firmware problem, skip the SMI handler on these machines before the + * D0 transition occurs. + */ +static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) +{ + struct resource *res; + void __iomem *addr; + u8 val; + + res = request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"); + if (!res) + return; + + addr = ioremap(s2idle_bug_mmio, 1); + if (!addr) + goto cleanup_resource; + + val = ioread8(addr); + iowrite8(val & ~BIT(0), addr); + + iounmap(addr); +cleanup_resource: + release_resource(res); + kfree(res); +} + +void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev) +{ + if (dev->quirks && dev->quirks->s2idle_bug_mmio) + amd_pmc_skip_nvme_smi_handler(dev->quirks->s2idle_bug_mmio); +} + +void amd_pmc_quirks_init(struct amd_pmc_dev *dev) +{ + const struct dmi_system_id *dmi_id; + + dmi_id = dmi_first_match(fwbug_list); + if (!dmi_id) + return; + dev->quirks = dmi_id->driver_data; + if (dev->quirks->s2idle_bug_mmio) + pr_info("Using s2idle quirk to avoid %s platform firmware bug\n", + dmi_id->ident); +} diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c index 7d3d080ff174..a8ca95a5d44c 100644 --- a/drivers/platform/x86/amd/pmc.c +++ b/drivers/platform/x86/amd/pmc.c @@ -28,6 +28,8 @@ #include #include +#include "pmc.h" + /* SMU communication registers */ #define AMD_PMC_REGISTER_MESSAGE 0x538 #define AMD_PMC_REGISTER_RESPONSE 0x980 @@ -146,29 +148,6 @@ static const struct amd_pmc_bit_map soc15_ip_blk[] = { {} }; -struct amd_pmc_dev { - void __iomem *regbase; - void __iomem *smu_virt_addr; - void __iomem *stb_virt_addr; - void __iomem *fch_virt_addr; - bool msg_port; - u32 base_addr; - u32 cpu_id; - u32 active_ips; - u32 dram_size; - u32 num_ips; - u32 s2d_msg_id; -/* SMU version information */ - u8 smu_program; - u8 major; - u8 minor; - u8 rev; - struct device *dev; - struct pci_dev *rdev; - struct mutex lock; /* generic mutex lock */ - struct dentry *dbgfs_dir; -}; - static bool enable_stb; module_param(enable_stb, bool, 0644); MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism"); @@ -891,6 +870,8 @@ static void amd_pmc_s2idle_restore(void) /* Notify on failed entry */ amd_pmc_validate_deepest(pdev); + + amd_pmc_process_restore_quirks(pdev); } static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = { @@ -1087,6 +1068,8 @@ static int amd_pmc_probe(struct platform_device *pdev) err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops); if (err) dev_warn(dev->dev, "failed to register LPS0 sleep handler, expect increased power consumption\n"); + if (!disable_workarounds) + amd_pmc_quirks_init(dev); } amd_pmc_dbgfs_register(dev); diff --git a/drivers/platform/x86/amd/pmc.h b/drivers/platform/x86/amd/pmc.h new file mode 100644 index 000000000000..c27bd6a5642f --- /dev/null +++ b/drivers/platform/x86/amd/pmc.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD SoC Power Management Controller Driver + * + * Copyright (c) 2023, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Author: Mario Limonciello + */ + +#ifndef PMC_H +#define PMC_H + +#include +#include + +struct amd_pmc_dev { + void __iomem *regbase; + void __iomem *smu_virt_addr; + void __iomem *stb_virt_addr; + void __iomem *fch_virt_addr; + bool msg_port; + u32 base_addr; + u32 cpu_id; + u32 active_ips; + u32 dram_size; + u32 num_ips; + u32 s2d_msg_id; +/* SMU version information */ + u8 smu_program; + u8 major; + u8 minor; + u8 rev; + struct device *dev; + struct pci_dev *rdev; + struct mutex lock; /* generic mutex lock */ + struct dentry *dbgfs_dir; + struct quirk_entry *quirks; +}; + +void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev); +void amd_pmc_quirks_init(struct amd_pmc_dev *dev); + +#endif /* PMC_H */ -- cgit From d194803325150c53ad228aedb6f6a82ac9ea6360 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 10 Jul 2023 13:39:34 -0500 Subject: platform/x86/amd: pmc: Apply nvme quirk to HP 15s-eq2xxx HP 15s-eq2xxx is an older Lucienne laptop that has a problem resuming from s2idle when IOMMU is enabled. The symptoms very closely resemble that of the Lenovo issues with NVME resume. Lucienne was released in a similar timeframe as the Renoir / Cezanne Lenovo laptops and they may have similar BIOS code. Applying the same quirk to this system allows the system to work with IOMMU enabled and s2idle resume to work. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2684 Signed-off-by: Mario Limonciello Link: https://lore.kernel.org/r/20230710183934.17315-3-mario.limonciello@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmc-quirks.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmc-quirks.c b/drivers/platform/x86/amd/pmc-quirks.c index 21a977004db8..362e7c0097d7 100644 --- a/drivers/platform/x86/amd/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc-quirks.c @@ -112,6 +112,15 @@ static const struct dmi_system_id fwbug_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), } }, + /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */ + { + .ident = "HP Laptop 15s-eq2xxx", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Laptop 15s-eq2xxx"), + } + }, {} }; -- cgit From 822507ca6affc8930a3919f326c79062354e8283 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Tue, 11 Jul 2023 15:33:44 +0530 Subject: platform/x86/amd: pmc: Add new ACPI ID AMDI000A Add new ACPI ID AMDI000A used by upcoming AMD platform to the pmc supported list of devices Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20230711100344.383948-1-Shyam-sundar.S-k@amd.com Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c index a8ca95a5d44c..c1e788b67a74 100644 --- a/drivers/platform/x86/amd/pmc.c +++ b/drivers/platform/x86/amd/pmc.c @@ -96,6 +96,7 @@ #define AMD_CPU_ID_CB 0x14D8 #define AMD_CPU_ID_PS 0x14E8 #define AMD_CPU_ID_SP 0x14A4 +#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 #define PMC_MSG_DELAY_MIN_US 50 #define RESPONSE_REGISTER_LOOP_MAX 20000 @@ -907,6 +908,7 @@ static const struct pci_device_id pmc_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RV) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_SP) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, { } }; @@ -1098,6 +1100,7 @@ static const struct acpi_device_id amd_pmc_acpi_ids[] = { {"AMDI0007", 0}, {"AMDI0008", 0}, {"AMDI0009", 0}, + {"AMDI000A", 0}, {"AMD0004", 0}, {"AMD0005", 0}, { } -- cgit From 5d3acd9d7a44ad9902e98e57013f028d5f4fc86c Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Tue, 11 Jul 2023 15:39:03 +0530 Subject: platform/x86/amd: pmf: Add new ACPI ID AMDI0103 Add new ACPI ID AMDI0103 used by upcoming AMD platform to the PMF supported list of devices. Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20230711100903.384151-1-Shyam-sundar.S-k@amd.com Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index 7780705917b7..d8732557f9db 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -40,6 +40,7 @@ /* List of supported CPU ids */ #define AMD_CPU_ID_RMB 0x14b5 #define AMD_CPU_ID_PS 0x14e8 +#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 #define PMF_MSG_DELAY_MIN_US 50 #define RESPONSE_REGISTER_LOOP_MAX 20000 @@ -242,6 +243,7 @@ out_unlock: static const struct pci_device_id pmf_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RMB) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, { } }; @@ -333,6 +335,7 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev *dev) static const struct acpi_device_id amd_pmf_acpi_ids[] = { {"AMDI0100", 0x100}, {"AMDI0102", 0}, + {"AMDI0103", 0}, { } }; MODULE_DEVICE_TABLE(acpi, amd_pmf_acpi_ids); -- cgit From f2ae72541d52a0bf50366840fe2238aaf111f7ae Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 11 Jul 2023 11:59:20 +0200 Subject: platform/x86/amd: pmc: Use release_mem_region() to undo request_mem_region_muxed() Muxed (mem) regions will wait in request_mem_region_muxed() if the region is busy (in use by another consumer) during the call. In order to wake-up possibly waiting other consumers of the region, it must be released by a release_mem_region() call, which will actually wake up any waiters. release_mem_region() also frees the resource created by request_mem_region_muxed(), avoiding the need for the unmatched kfree(). Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20230711095920.264308-1-hdegoede@redhat.com --- drivers/platform/x86/amd/pmc-quirks.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmc-quirks.c b/drivers/platform/x86/amd/pmc-quirks.c index 362e7c0097d7..ad702463a65d 100644 --- a/drivers/platform/x86/amd/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc-quirks.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "pmc.h" @@ -135,12 +134,10 @@ static const struct dmi_system_id fwbug_list[] = { */ static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) { - struct resource *res; void __iomem *addr; u8 val; - res = request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"); - if (!res) + if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80")) return; addr = ioremap(s2idle_bug_mmio, 1); @@ -152,8 +149,7 @@ static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) iounmap(addr); cleanup_resource: - release_resource(res); - kfree(res); + release_mem_region(s2idle_bug_mmio, 1); } void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev) -- cgit From 839e90e75e695b3d9ee17f5a2811e7ee5aea8d4a Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Fri, 14 Jul 2023 20:14:34 +0530 Subject: platform/x86/amd/pmf: reduce verbosity of apmf_get_system_params apmf_get_system_params() failure is not a critical event, reduce its verbosity from dev_err to dev_dbg. Signed-off-by: Mario Limonciello Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20230714144435.1239776-1-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 081e84e116e7..732b15b392ab 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -289,7 +289,7 @@ int apmf_acpi_init(struct amd_pmf_dev *pmf_dev) ret = apmf_get_system_params(pmf_dev); if (ret) { - dev_err(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); + dev_dbg(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); goto out; } -- cgit From 33c9ab5b493a0e922b06c12fed4fdcb862212cda Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Fri, 14 Jul 2023 20:14:35 +0530 Subject: platform/x86/amd/pmf: Notify OS power slider update APMF fn8 can notify EC about the OS slider position change. Add this capability to the PMF driver so that it can call the APMF fn8 based on the changes in the Platform profile events. Co-developed-by: Mario Limonciello Signed-off-by: Mario Limonciello Signed-off-by: Patil Rajesh Reddy Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20230714144435.1239776-2-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/acpi.c | 21 +++++++++++ drivers/platform/x86/amd/pmf/core.c | 9 ++++- drivers/platform/x86/amd/pmf/pmf.h | 16 ++++++++ drivers/platform/x86/amd/pmf/sps.c | 74 +++++++++++++++++++++++++++++++++++-- 4 files changed, 114 insertions(+), 6 deletions(-) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 732b15b392ab..3fc5e4547d9f 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -106,6 +106,27 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, data, sizeof(*data)); } +int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event) +{ + struct os_power_slider args; + struct acpi_buffer params; + union acpi_object *info; + int err = 0; + + args.size = sizeof(args); + args.slider_event = event; + + params.length = sizeof(args); + params.pointer = (void *)&args; + + info = apmf_if_call(pdev, APMF_FUNC_OS_POWER_SLIDER_UPDATE, ¶ms); + if (!info) + err = -EIO; + + kfree(info); + return err; +} + static void apmf_sbios_heartbeat_notify(struct work_struct *work) { struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work); diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index d8732557f9db..57bf1a9f0e76 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -72,7 +72,11 @@ static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long return NOTIFY_DONE; } - amd_pmf_set_sps_power_limits(pmf); + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) + amd_pmf_set_sps_power_limits(pmf); + + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) + amd_pmf_power_slider_update_event(pmf); return NOTIFY_OK; } @@ -297,7 +301,8 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev) int ret; /* Enable Static Slider */ - if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) || + is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { amd_pmf_init_sps(dev); dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call; power_supply_reg_notifier(&dev->pwr_src_notifier); diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 06c30cdc0573..deba88e6e4c8 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -21,6 +21,7 @@ #define APMF_FUNC_SBIOS_HEARTBEAT 4 #define APMF_FUNC_AUTO_MODE 5 #define APMF_FUNC_SET_FAN_IDX 7 +#define APMF_FUNC_OS_POWER_SLIDER_UPDATE 8 #define APMF_FUNC_STATIC_SLIDER_GRANULAR 9 #define APMF_FUNC_DYN_SLIDER_AC 11 #define APMF_FUNC_DYN_SLIDER_DC 12 @@ -44,6 +45,14 @@ #define GET_STT_LIMIT_APU 0x20 #define GET_STT_LIMIT_HS2 0x21 +/* OS slider update notification */ +#define DC_BEST_PERF 0 +#define DC_BETTER_PERF 1 +#define DC_BATTERY_SAVER 3 +#define AC_BEST_PERF 4 +#define AC_BETTER_PERF 5 +#define AC_BETTER_BATTERY 6 + /* Fan Index for Auto Mode */ #define FAN_INDEX_AUTO 0xFFFFFFFF @@ -193,6 +202,11 @@ struct amd_pmf_static_slider_granular { struct apmf_sps_prop_granular prop[POWER_SOURCE_MAX][POWER_MODE_MAX]; }; +struct os_power_slider { + u16 size; + u8 slider_event; +} __packed; + struct fan_table_control { bool manual; unsigned long fan_id; @@ -383,6 +397,7 @@ int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev); int amd_pmf_get_power_source(void); int apmf_install_handler(struct amd_pmf_dev *pmf_dev); +int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); /* SPS Layer */ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); @@ -393,6 +408,7 @@ void amd_pmf_deinit_sps(struct amd_pmf_dev *dev); int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, struct apmf_static_slider_granular_output *output); bool is_pprof_balanced(struct amd_pmf_dev *pmf); +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev); int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx); diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c index 445ff053b4df..ab69d517a36a 100644 --- a/drivers/platform/x86/amd/pmf/sps.c +++ b/drivers/platform/x86/amd/pmf/sps.c @@ -174,14 +174,77 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) return mode; } +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) +{ + u8 mode, flag = 0; + int src; + + mode = amd_pmf_get_pprof_modes(dev); + if (mode < 0) + return mode; + + src = amd_pmf_get_power_source(); + + if (src == POWER_SOURCE_AC) { + switch (mode) { + case POWER_MODE_PERFORMANCE: + flag |= BIT(AC_BEST_PERF); + break; + case POWER_MODE_BALANCED_POWER: + flag |= BIT(AC_BETTER_PERF); + break; + case POWER_MODE_POWER_SAVER: + flag |= BIT(AC_BETTER_BATTERY); + break; + default: + dev_err(dev->dev, "unsupported platform profile\n"); + return -EOPNOTSUPP; + } + + } else if (src == POWER_SOURCE_DC) { + switch (mode) { + case POWER_MODE_PERFORMANCE: + flag |= BIT(DC_BEST_PERF); + break; + case POWER_MODE_BALANCED_POWER: + flag |= BIT(DC_BETTER_PERF); + break; + case POWER_MODE_POWER_SAVER: + flag |= BIT(DC_BATTERY_SAVER); + break; + default: + dev_err(dev->dev, "unsupported platform profile\n"); + return -EOPNOTSUPP; + } + } + + apmf_os_power_slider_update(dev, flag); + + return 0; +} + static int amd_pmf_profile_set(struct platform_profile_handler *pprof, enum platform_profile_option profile) { struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); + int ret = 0; pmf->current_profile = profile; - return amd_pmf_set_sps_power_limits(pmf); + /* Notify EC about the slider position change */ + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { + ret = amd_pmf_power_slider_update_event(pmf); + if (ret) + return ret; + } + + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + ret = amd_pmf_set_sps_power_limits(pmf); + if (ret) + return ret; + } + + return 0; } int amd_pmf_init_sps(struct amd_pmf_dev *dev) @@ -189,10 +252,13 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev) int err; dev->current_profile = PLATFORM_PROFILE_BALANCED; - amd_pmf_load_defaults_sps(dev); - /* update SPS balanced power mode thermals */ - amd_pmf_set_sps_power_limits(dev); + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + amd_pmf_load_defaults_sps(dev); + + /* update SPS balanced power mode thermals */ + amd_pmf_set_sps_power_limits(dev); + } dev->pprof.profile_get = amd_pmf_profile_get; dev->pprof.profile_set = amd_pmf_profile_set; -- cgit From 785c00993dc4c4bb2f7b0f3a3f29c03a6f7aab2e Mon Sep 17 00:00:00 2001 From: Yang Li Date: Thu, 27 Jul 2023 09:43:15 +0800 Subject: platform/x86/amd/pmf: Fix unsigned comparison with less than zero The return value from the call to amd_pmf_get_pprof_modes() is int. However, the return value is being assigned to an unsigned char variable 'mode', so making 'mode' an int. silence the warning: ./drivers/platform/x86/amd/pmf/sps.c:183:5-9: WARNING: Unsigned expression compared with zero: mode < 0 Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=5995 Signed-off-by: Yang Li Link: https://lore.kernel.org/r/20230727014315.51375-1-yang.lee@linux.alibaba.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/sps.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c index ab69d517a36a..a70e67749be3 100644 --- a/drivers/platform/x86/amd/pmf/sps.c +++ b/drivers/platform/x86/amd/pmf/sps.c @@ -176,7 +176,8 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) { - u8 mode, flag = 0; + u8 flag = 0; + int mode; int src; mode = amd_pmf_get_pprof_modes(dev); -- cgit