git: 758578370f6b - main - amdsmu: Hints on what to do if IP block blocking S0i3

From: Aymeric Wibo <obiwac_at_FreeBSD.org>
Date: Fri, 18 Sep 2026 10:59:28 UTC
The branch main has been updated by obiwac:

URL: https://cgit.FreeBSD.org/src/commit/?id=758578370f6b726299c19f0e87355b91af1b90e5

commit 758578370f6b726299c19f0e87355b91af1b90e5
Author:     Aymeric Wibo <obiwac@FreeBSD.org>
AuthorDate: 2026-09-18 10:52:03 +0000
Commit:     Aymeric Wibo <obiwac@FreeBSD.org>
CommitDate: 2026-09-18 10:59:14 +0000

    amdsmu: Hints on what to do if IP block blocking S0i3
    
    Reviewed by:    olce
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59674
---
 sys/dev/amdsmu/amdsmu.c | 23 +++++++++++++++++++++++
 sys/dev/amdsmu/amdsmu.h | 22 ++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/sys/dev/amdsmu/amdsmu.c b/sys/dev/amdsmu/amdsmu.c
index 5902e5e9af89..f7edc073efea 100644
--- a/sys/dev/amdsmu/amdsmu.c
+++ b/sys/dev/amdsmu/amdsmu.c
@@ -323,6 +323,7 @@ amdsmu_resume_check(device_t dev, enum power_stype stype)
 	struct amdsmu_softc *sc = device_get_softc(dev);
 	struct amdsmu_metrics *m = &sc->metrics;
 	bool any_blocking = false;
+	const struct amdsmu_diagnostics *d;
 
 	if (stype != POWER_STYPE_SUSPEND_TO_IDLE)
 		return;
@@ -348,6 +349,18 @@ amdsmu_resume_check(device_t dev, enum power_stype stype)
 		 */
 		if (m->ip_block_last_active_time[i] < m->time_last_in_sw_drips)
 			continue;
+		/* Check if this IP block should be ignored. */
+		d = NULL;
+		for (size_t j = 0; j < nitems(amdsmu_diagnostics); j++) {
+			if (strcmp(amdsmu_diagnostics[j].blocking_ip_block,
+			    sc->product->ip_blocks_names[i]) != 0)
+				continue;
+			d = &amdsmu_diagnostics[j];
+			break;
+		}
+		if (d != NULL && d->ignore)
+			continue;
+
 		if (!any_blocking) {
 			device_printf(dev,
 			    "IP blocks that blocked S0i3 entry:\n");
@@ -356,6 +369,16 @@ amdsmu_resume_check(device_t dev, enum power_stype stype)
 		device_printf(dev, "  %s (active for %ju us)\n",
 		    sc->product->ip_blocks_names[i],
 		    (uintmax_t)m->ip_block_last_active_time[i]);
+
+		if (d == NULL)
+			continue;
+		if (d->expected_module != NULL &&
+		    devclass_find(d->expected_module) == NULL)
+			device_printf(dev,
+			    "    hint: load %s to allow this block to "
+			    "suspend\n", d->expected_module);
+		if (d->extra != NULL)
+			device_printf(dev, "    hint: %s\n", d->extra);
 	}
 
 	if (!any_blocking)
diff --git a/sys/dev/amdsmu/amdsmu.h b/sys/dev/amdsmu/amdsmu.h
index 3b600fab118d..ede275ac7168 100644
--- a/sys/dev/amdsmu/amdsmu.h
+++ b/sys/dev/amdsmu/amdsmu.h
@@ -115,6 +115,28 @@ static const struct amdsmu_product {
 	 */
 };
 
+static const struct amdsmu_diagnostics {
+	const char	*blocking_ip_block;
+	bool		ignore;
+	const char	*expected_module;
+	const char	*extra;
+} amdsmu_diagnostics[] = {
+	{ "CPU", false, NULL, "this can happen due to other IP blocks or "
+	    "because the system was on AC power" },
+	{ "MPM", false, NULL, "this can happen due to other IP blocks or "
+	    "because the system was on AC power" },
+	{ "GFX", false, "amdgpu", NULL },
+	{ "DISPLAY", false, "amdgpu", NULL },
+	/*
+	 * On Phoenix, these seem to report USB4, not USB3 as their names would
+	 * suggest.
+	 */
+	{ "USB3_0", false, "tb", "see thunderbolt(4)" },
+	{ "USB3_1", false, "tb", "see thunderbolt(4)" },
+	/* On Phoenix, the SMU seems to report garbage for this IP block. */
+	{ "USB4_0", true, NULL, NULL },
+};
+
 struct amdsmu_softc {
 	const struct amdsmu_product	*product;