Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109583986
D48721.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D48721.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D48721: amdsmu: Sleep entry/exit hints for PMFW
Attached
Detach File
Event Timeline
Log In to Comment