Skip to content

J713: docked deep sleep by default; brcmfmac reset after a sleep - #1855

Merged
DjDeveloperr merged 3 commits into
integration/aurorafrom
j713/cio-s2r-default
Nov 13, 2026
Merged

DjDeveloperr merged 3 commits into
integration/aurorafrom
j713/cio-s2r-default

Conversation

@erikwb

@erikwb erikwb commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

Follow-ups to #1314 for the J713's deep sleep.

  • USB4/Thunderbolt devices no longer block suspend. pcie_apple.cio_s2r and thunderbolt_apple.cio_s2r now default to on.
    • Before: with them off and deep the J713 default, a dock or other USB4/Thunderbolt device in a port made the T8132 PHY refuse every system sleep. DWC3 stops its host at PM_SUSPEND_PREPARE, the PHY keeps its CIO mode, and nothing hands the link to the NHI.
    • Now: the NHI takes the host router, the CIO PHY and the tunneled PCIe-C port through the deep sleep.
    • Refusals kept: the NHI still refuses a deep sleep it can't take over (no PCIe-C tunnel, XDomain rings open, the cable state changing), and the PHY then refuses the sleep as before.
    • Scope: both checks stay limited to the J713 (apple,j713 with the T8132 ACIO and PCIe-C), so other machines are unaffected. cio_s2r=0 on either module restores the old behaviour.
    • Docked s2idle: with the handoff on, the tunneled port keeps its link for an s2idle and refuses the s2idle if it can't keep the link, instead of stopping the port.
    • Older DT: a DART that an older device tree gives no sleep path no longer fails the PCIe-C probe. The port keeps the stock resume ordering, and a docked deep sleep is refused.
  • brcmfmac: reset firmware that died during a sleep.
    • Before: while the platform owns the radio for a system sleep, reset work is blocked. A pending reset is cancelled when the lease starts, a new one isn't queued, and brcmf_pcie_reset() refuses. Nothing asked for the reset again when the lease ended, so firmware that died during the sleep stayed dead until the driver was reloaded.
    • Now: the firmware-death handler records that it wants a reset, a reset that runs clears it, and the lease end queues the reset again if it is still wanted. The recovery limit still applies.
    • Tests: a replay case in brcmfmac-sleep-lifetime-tests with a mutation that drops it. The recovery test checks the flag per reset and past the limit, with two new mutations.

Validation on this branch:

  • Build and host tests: full arm64 Image, modules and DTBs. checkpatch is clean on all three commits. The brcmfmac host suites pass, and every mutation is rejected.
  • J713 setup: 24 GB, with a CalDigit TS5 (USB4 at 20 Gb/s, PCIe tunnel with the dock's Ethernet, two DisplayPort monitors). Aura 1.0.0b11. No cio_s2r option on the command line; both parameters read Y.
  • J713 run: one suspend test at the platform stage, then one real deep sleep with an RTC wake on the same boot.
  • J713 results: every NHI, PHY, DART and PCIe-C stop and restore step ran, and the Wi-Fi and Bluetooth recovery after power loss completed. The dock came back at 20 Gb/s with Ethernet up and both monitors connected. No kernel warnings, no taint.

Not covered:

  • Repeated sleeps on one boot.
  • Wake sources other than the RTC.
  • Docks other than the TS5.
  • A firmware death during a sleep on hardware: the brcmfmac change is covered by the host tests only.
  • A docked freeze while deep is the default: it is still refused at the PHY, because DWC3 stops its host and the NHI handoff only runs for a deep sleep.

These changes were developed and tested by Claude (Anthropic), working with me on the J713.

While deep sleep is the J713 default, a USB4/Thunderbolt device in a
port makes the PHY refuse every system sleep: DWC3 stops its host at
PM_SUSPEND_PREPARE, the PHY keeps its CIO mode, and with this parameter
off nothing hands the link to the NHI. Turn the PCIe-C side of that
handoff on by default. cio_s2r=0 still selects the old behaviour.

With the handoff on, the port's suspend keeps its link for an s2idle
and refuses one if the link can't be kept, instead of stopping the port
as it did before.

A DART that an older device tree gives no sleep path no longer has to
fail the port's probe. The port then keeps the stock resume ordering
and the NHI refuses a docked deep sleep, as with the parameter off.

Signed-off-by: Erik Bourget <erik@ebourget.net>
…y default

While deep sleep is the J713 default, a dock in a port blocks every
system sleep unless the NHI owns the host router through it. Make that
the default. The NHI still refuses a deep sleep it can't take over: one
without a PCIe-C tunnel, with XDomain rings open, or with the cable
state changing. cio_s2r=0 still refuses a docked deep sleep as before.

Signed-off-by: Erik Bourget <erik@ebourget.net>
While the platform owns the radio for a system sleep, reset work is
blocked: a pending reset is cancelled when the lease starts, a new one
is not queued, and brcmf_pcie_reset() refuses. Nothing asked for the
reset again when the lease ended, so firmware that died during the
sleep stayed dead until the driver was reloaded.

Note a reset the firmware death handler asked for and clear the note
when a reset runs. When the lease ends, queue the reset again if it is
still wanted. The recovery limit still applies, because only a death
under that limit asks for a reset.

Signed-off-by: Erik Bourget <erik@ebourget.net>

@DjDeveloperr DjDeveloperr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 324fb8579a02; approving. Thanks, Erik.

  • cio_s2r default on. Both uses stay behind the T8132 ACIO/PCIe-C hardware and apple,j713, so other machines take apple_pcie_tunnel_add_link() as before. On the J713, an older DT whose DART has no sleep path now keeps the tunnel with a warning instead of failing the PCIe-C probe.
  • An undocked J713 sleep is unaffected. The NHI exists only between apple_cio_start() and apple_cio_stop(), so with nothing plugged in its prepare never runs. A USB4 device without a PCIe tunnel is still refused, as before.
  • brcmfmac.
    • reset_wanted is set only after the recovery-limit check, so the limit still holds.
    • A reset that runs clears it.
    • It is replayed only from brcmf_pcie_sleep_finish(), the J713 radio lease's end. Elsewhere it is a flag that is set and cleared with no other effect.
  • CI. host-tests passed on the merge with ccc5a9d41de7. Since then integration/aurora gained only asm/mmu_context.h (#1509) and g17/sleep.rs (#1839). Neither is near these files, and the merge with the current tip is clean.
  • J713 evidence: the docked deep sleep in the description. A follow-up we'd welcome: several docked sleeps on one boot, and a wake source other than the RTC.

@DjDeveloperr
DjDeveloperr merged commit 4e5be40 into integration/aurora Nov 13, 2026
1 check passed
@DjDeveloperr

Copy link
Copy Markdown
Contributor

Merged as 4e5be40d8101 onto integration/aurora 03f060b251c8. The merge tree is the clean merge-tree I checked against that tip; the base had moved only by aop.rs (#1645) since the review. The functional change is J713-only, so the J713 run in the description is its hardware evidence. It also goes into the J700 kit that verifies #1314 after its merge. Thanks, Erik.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants