Page MenuHomeFreeBSD

D48721.diff
No OneTemporary

D48721.diff

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -3309,14 +3309,53 @@
}
enum acpi_sleep_state {
- ACPI_SS_NONE = 0,
- ACPI_SS_GPE_SET = 1 << 0,
- ACPI_SS_DEV_SUSPEND = 1 << 1,
- ACPI_SS_SPMC_ENTER = 1 << 2,
- ACPI_SS_SLP_PREP = 1 << 3,
- ACPI_SS_SLEPT = 1 << 4,
+ ACPI_SS_NONE = 0,
+ ACPI_SS_GPE_SET = 1 << 0,
+ ACPI_SS_DEV_SUSPEND = 1 << 1,
+ ACPI_SS_SPMC_ENTER = 1 << 2,
+ ACPI_SS_AMDSMU_ENTER = 1 << 3,
+ ACPI_SS_SLP_PREP = 1 << 4,
+ ACPI_SS_SLEPT = 1 << 5,
};
+static int
+acpi_amdsmu_get_device(struct acpi_softc *sc, device_t *dev)
+{
+ devclass_t amdsmu_dc = devclass_find("amdsmu");
+
+ MPASS(dev != NULL);
+ if (amdsmu_dc == NULL) {
+ device_printf(sc->acpi_dev, "amdsmu device class not found\n");
+ return (ENXIO);
+ }
+ *dev = devclass_get_device(amdsmu_dc, 0);
+ if (*dev == NULL) {
+ device_printf(sc->acpi_dev, "no amdsmu device found\n");
+ return (ENXIO);
+ }
+ return (0);
+}
+
+static int
+acpi_amdsmu_enter(struct acpi_softc *sc)
+{
+ device_t amdsmu;
+
+ if (acpi_amdsmu_get_device(sc, &amdsmu) != 0)
+ return (ENXIO);
+ return (DEVICE_AMDSMU_ENTER_SLEEP(amdsmu));
+}
+
+static int
+acpi_amdsmu_exit(struct acpi_softc *sc)
+{
+ device_t amdsmu;
+
+ if (acpi_amdsmu_get_device(sc, &amdsmu) != 0)
+ return (ENXIO);
+ return (DEVICE_AMDSMU_EXIT_SLEEP(amdsmu));
+}
+
static void
do_standby(struct acpi_softc *sc, enum acpi_sleep_state *slp_state,
register_t rflags)
@@ -3517,6 +3556,8 @@
else
slp_state |= ACPI_SS_SPMC_ENTER;
}
+ if (acpi_amdsmu_enter(sc) == 0)
+ slp_state |= ACPI_SS_AMDSMU_ENTER;
if (stype != STYPE_SUSPEND_TO_IDLE) {
status = AcpiEnterSleepStatePrep(stype);
@@ -3570,6 +3611,10 @@
sc->acpi_stype = STYPE_AWAKE;
slp_state &= ~ACPI_SS_GPE_SET;
}
+ if (slp_state & ACPI_SS_AMDSMU_ENTER) {
+ acpi_amdsmu_exit(sc);
+ slp_state &= ~ACPI_SS_AMDSMU_ENTER;
+ }
if (slp_state & ACPI_SS_SPMC_ENTER) {
MPASS(sc->acpi_spmc_device != NULL);
MPASS(sc->acpi_spmc_exit != NULL);
diff --git a/sys/dev/amdsmu/amdsmu.c b/sys/dev/amdsmu/amdsmu.c
--- a/sys/dev/amdsmu/amdsmu.c
+++ b/sys/dev/amdsmu/amdsmu.c
@@ -44,6 +44,7 @@
enum amdsmu_msg {
SMU_MSG_GETSMUVERSION = 0x02,
+ SMU_MSG_SLEEP_HINT = 0x03,
SMU_MSG_LOG_GETDRAM_ADDR_HI = 0x04,
SMU_MSG_LOG_GETDRAM_ADDR_LO = 0x05,
SMU_MSG_LOG_START = 0x06,
@@ -470,6 +471,29 @@
0, "Total time spent in software DRIPS (SW DRIPS) (us)");
}
+static int
+amdsmu_enter(device_t dev)
+{
+
+ if (amdsmu_cmd(dev, SMU_MSG_SLEEP_HINT, true, NULL) != 0) {
+ device_printf(dev, "failed to hint to SMU to enter sleep");
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+amdsmu_exit(device_t dev)
+{
+
+ if (amdsmu_cmd(dev, SMU_MSG_SLEEP_HINT, false, NULL) != 0) {
+ device_printf(dev, "failed to hint to SMU to exit sleep");
+ return (-1);
+ }
+ amdsmu_dump_metrics(dev);
+ return (0);
+}
+
static int
amdsmu_attach(device_t dev)
{
@@ -550,6 +574,8 @@
DEVMETHOD(device_probe, amdsmu_probe),
DEVMETHOD(device_attach, amdsmu_attach),
DEVMETHOD(device_detach, amdsmu_detach),
+ DEVMETHOD(device_amdsmu_enter_sleep, amdsmu_enter),
+ DEVMETHOD(device_amdsmu_exit_sleep, amdsmu_exit),
DEVMETHOD_END
};
diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m
--- a/sys/kern/bus_if.m
+++ b/sys/kern/bus_if.m
@@ -31,7 +31,7 @@
/**
* @defgroup BUS bus - KObj methods for drivers of devices with children
- * @brief A set of methods required device drivers that support
+ * @brief A set of methods required for device drivers that support
* child devices.
* @{
*/
diff --git a/sys/kern/device_if.m b/sys/kern/device_if.m
--- a/sys/kern/device_if.m
+++ b/sys/kern/device_if.m
@@ -358,3 +358,34 @@
METHOD void * register {
device_t dev;
} DEFAULT null_register;
+
+/**
+ * @brief Hint to the AMD SMU that we intend to enter sleep.
+ *
+ * Must be called by the ACPI sleep routine during s2idle before actually
+ * idling the CPU but after calling the SPMC entry function, if one was set on
+ * the ACPI softc.
+ *
+ * @param dev the amdsmu device to hint entry to
+ *
+ * @retval 0 success
+ * @retval ETIMEDOUT timed out trying to send a message to the SMU
+ */
+METHOD int amdsmu_enter_sleep {
+ device_t dev;
+};
+
+/**
+ * @brief Hint to the AMD SMU that we are exiting sleep.
+ *
+ * Must be called by the ACPI sleep routine during s2idle after waking the CPU
+ * but before calling the SPMC exit function, if one was set on the ACPI softc.
+ *
+ * @param dev the amdsmu device to hint exit to
+ *
+ * @retval 0 success
+ * @retval ETIMEDOUT timed out trying to send a message to the SMU
+ */
+METHOD int amdsmu_exit_sleep {
+ device_t dev;
+};

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 8, 1:20 AM (21 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16519533
Default Alt Text
D48721.diff (4 KB)

Event Timeline