diff options
| author | Aymeric Wibo <obiwac@FreeBSD.org> | 2026-09-18 10:52:03 +0000 |
|---|---|---|
| committer | Aymeric Wibo <obiwac@FreeBSD.org> | 2026-09-18 10:59:14 +0000 |
| commit | 758578370f6b726299c19f0e87355b91af1b90e5 (patch) | |
| tree | 213e7ae63cba02c12b7512408972da3ec2d84b92 | |
| parent | a23fa3fe1c0aa4e529b26bbec17d17571f8708fd (diff) | |
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
| -rw-r--r-- | sys/dev/amdsmu/amdsmu.c | 23 | ||||
| -rw-r--r-- | sys/dev/amdsmu/amdsmu.h | 22 |
2 files changed, 45 insertions, 0 deletions
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; |
