From a903e442c8e9b9551ad1b31d686153eeba59c0c0 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 13 Jul 2024 15:38:21 +0000 Subject: [PATCH] Implement some more suspend/resume Linux compat such that inteldrm(4) can achieve RC6 and save a significant amount of power for S0i. ok jsg@ --- sys/dev/pci/drm/drm_drv.c | 10 ++++++++++ sys/dev/pci/drm/drm_linux.c | 14 +++++++++++++- sys/dev/pci/drm/i915/gt/intel_gt_pm.c | 4 ---- sys/dev/pci/drm/include/generated/autoconf.h | 1 + sys/dev/pci/drm/include/linux/acpi.h | 3 +++ sys/dev/pci/drm/include/linux/suspend.h | 14 ++++++++++++++ 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 4193f4ce1c3..3cf746c6d54 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -1548,10 +1549,19 @@ drm_activate(struct device *self, int act) switch (act) { case DVACT_QUIESCE: +#ifdef CONFIG_ACPI + if (acpi_softc && acpi_softc->sc_state == ACPI_STATE_S3) + pm_suspend_target_state = PM_SUSPEND_MEM; + else + pm_suspend_target_state = PM_SUSPEND_TO_IDLE; +#else + pm_suspend_target_state = PM_SUSPEND_TO_IDLE; +#endif drm_quiesce(dev); break; case DVACT_WAKEUP: drm_wakeup(dev); + pm_suspend_target_state = PM_SUSPEND_ON; break; } diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c index 3204b4a0af5..2d3e9196c2b 100644 --- a/sys/dev/pci/drm/drm_linux.c +++ b/sys/dev/pci/drm/drm_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_linux.c,v 1.114 2024/06/13 18:05:54 kettenis Exp $ */ +/* $OpenBSD: drm_linux.c,v 1.115 2024/07/13 15:38:21 kettenis Exp $ */ /* * Copyright (c) 2013 Jonathan Gray * Copyright (c) 2015, 2016 Mark Kettenis @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -1345,6 +1346,8 @@ vga_put(struct pci_dev *pdev, int rsrc) #endif +suspend_state_t pm_suspend_target_state; + /* * ACPI types and interfaces. */ @@ -1360,6 +1363,8 @@ vga_put(struct pci_dev *pdev, int rsrc) #include #include +struct acpi_fadt acpi_gbl_FADT; + acpi_status acpi_get_table(const char *sig, int instance, struct acpi_table_header **hdr) @@ -2851,6 +2856,13 @@ drm_linux_init(void) kmap_atomic_va = (vaddr_t)km_alloc(PAGE_SIZE, &kv_any, &kp_none, &kd_waitok); + +#if NACPI > 0 + if (acpi_softc) { + memcpy(&acpi_gbl_FADT, acpi_softc->sc_fadt, + sizeof(acpi_gbl_FADT)); + } +#endif } void diff --git a/sys/dev/pci/drm/i915/gt/intel_gt_pm.c b/sys/dev/pci/drm/i915/gt/intel_gt_pm.c index 84451257e1b..ad361eb56e7 100644 --- a/sys/dev/pci/drm/i915/gt/intel_gt_pm.c +++ b/sys/dev/pci/drm/i915/gt/intel_gt_pm.c @@ -326,7 +326,6 @@ void intel_gt_suspend_prepare(struct intel_gt *gt) wait_for_suspend(gt); } -#ifdef notyet static suspend_state_t pm_suspend_target(void) { #if IS_ENABLED(CONFIG_SUSPEND) && IS_ENABLED(CONFIG_PM_SLEEP) @@ -335,7 +334,6 @@ static suspend_state_t pm_suspend_target(void) return PM_SUSPEND_TO_IDLE; #endif } -#endif void intel_gt_suspend_late(struct intel_gt *gt) { @@ -361,10 +359,8 @@ void intel_gt_suspend_late(struct intel_gt *gt) * powermanagement enabled, but we also retain system state and so * it remains safe to keep on using our allocated memory. */ -#ifdef notyet if (pm_suspend_target() == PM_SUSPEND_TO_IDLE) return; -#endif with_intel_runtime_pm(gt->uncore->rpm, wakeref) { intel_rps_disable(>->rps); diff --git a/sys/dev/pci/drm/include/generated/autoconf.h b/sys/dev/pci/drm/include/generated/autoconf.h index adcef50e28b..9c8565e7862 100644 --- a/sys/dev/pci/drm/include/generated/autoconf.h +++ b/sys/dev/pci/drm/include/generated/autoconf.h @@ -93,5 +93,6 @@ #endif #if defined(SUSPEND) || defined(HIBERNATE) +#define CONFIG_SUSPEND 1 #define CONFIG_PM_SLEEP 1 #endif diff --git a/sys/dev/pci/drm/include/linux/acpi.h b/sys/dev/pci/drm/include/linux/acpi.h index b10d28eaba1..b15702c4687 100644 --- a/sys/dev/pci/drm/include/linux/acpi.h +++ b/sys/dev/pci/drm/include/linux/acpi.h @@ -88,4 +88,7 @@ int unregister_acpi_notifier(struct notifier_block *); int acpi_target_system_state(void); +extern struct acpi_fadt acpi_gbl_FADT; +#define ACPI_FADT_LOW_POWER_S0 (1 << 21) + #endif diff --git a/sys/dev/pci/drm/include/linux/suspend.h b/sys/dev/pci/drm/include/linux/suspend.h index e69de29bb2d..223844e664d 100644 --- a/sys/dev/pci/drm/include/linux/suspend.h +++ b/sys/dev/pci/drm/include/linux/suspend.h @@ -0,0 +1,14 @@ +/* Public domain. */ + +#ifndef _LINUX_SUSPEND_H +#define _LINUX_SUSPEND_H + +typedef int suspend_state_t; + +#define PM_SUSPEND_ON 0 +#define PM_SUSPEND_MEM 1 +#define PM_SUSPEND_TO_IDLE 2 + +extern suspend_state_t pm_suspend_target_state; + +#endif -- 2.20.1