Skip to content

Neo wake follow-ups: PMP wait after a sleep, SPMI stray interrupts, debug-link contract after a refused re-sleep - #1398

Closed
DjDeveloperr wants to merge 4 commits into
fix/apple-sleep-debug-cut-wakesfrom
fix/apple-sleep-refused-resleep
Closed

DjDeveloperr wants to merge 4 commits into
fix/apple-sleep-debug-cut-wakesfrom
fix/apple-sleep-refused-resleep

Conversation

@DjDeveloperr

Copy link
Copy Markdown
Contributor

Three wake follow-ups on #1374, from the Neo's final validation on the new Fedora install.

cpufreq: the PMP gets its 30 s again after a firmware sleep. Every wake logged PMP not running after 30 s (-11): fast die-temperature limit unavailable, CPUs 0,5 stay limited to 2688000 kHz. The PMP is stopped by the sleep and restarted only after the CPUs are back, so the first fast-die samples found it down. Since the boot was older than 30 s, that counted as a PMP that never came up, and sampling dropped to its 1 s give-up rate. The window now restarts at the suspend; jiffies don't count the sleep. Neo: 0 lines in 9 wakes on fin3, 0 on fin5 (before: one per boot, at the first wake). scaling_max_freq is back at 4044000 after the wake.

spmi: pending sources nothing uses are cleared, and the acks are flushed. After every firmware sleep the USB-PD SPMI controller fired its chained interrupt twice with nothing to run, and each time we got a bad_chained_irq dump for apple_spmi_irq_handler. Read at those interrupts (TEST kernels):

  • the PD controllers' even lines were pending next to the odd ones tipd uses: ACK 0xd1c00/0x1450 against the enables 0x22000/0x28a0;
  • another queue's response vector was pending in the vectors' word (0x80 next to ours);
  • tipd's own line was pending while the resume still had it masked.

The handler now clears pending sources that no driver has mapped, and the other vectors' responses, as probe does. A mapped source that is pending while masked isn't reported. The ACK block is read back before the parent is unmasked. Neo: 2 dumps per wake before, 1 per wake after (fin5, and fin6 with the read-back). The last one is still open: at that interrupt nothing of ours is pending in the peripheral words.

tipd cd321x: get the PD contract back before rearming the debug link. On 11-09 (fin1 soak, cycle 2) a deep sleep woken by its own debug-link cut slept again as a dark wake, and that second sleep was refused: an early wake event, no device error. The GPU's sleep refused before the commit: GPU firmware never stopped was only a consequence: the refusal came before the commit, where the GPU firmware is stopped. After that the rearm failed all 40 tries at the debug VDM. The partner had dropped the contract (1-0c POWER_STATUS 0), both ends sat at default USB power, and Debug USB was gone until a replug. Now, after 4 failed tries, if the port has no contract, the rearm does what the cut does: a cold reset (Gaid), a wait for the contract, at most 3 times. Then it sets the controller up again as after the cut and continues the tries.

Limits, stated plainly:

  • A synthetic repro (TEST knobs: the SMC warned before the cut so the cut wakes the sleep, then the dark-wake re-sleep aborted with an early wake event) refused the re-sleep as on 11-09. That time the contract survived and the link was rearmed on the first try, so the new recovery path did not run. It has not run on hardware yet.
  • The same repro showed the Neo's own 1-0c typec partner missing after the refusal (failed to place Type-C mux in safe mode: -110, retrying; ATC Pipehandler lock not acked) until the next sleep brought it back. That is not fixed here.

Tested on the J700 with the kernel #1374 + #1377 + #1393 + this, Fedora 44's kernel config plus the sleep symbols: the rig RAM boot (stage2-15) and the distro boot (GRUB, LUKS, splash). Results are in the final-validation notes.

🤖 Generated with Claude Code

A firmware-driven sleep stops the PMP, and its driver starts it again only
after the CPUs are back online. The fast die-temperature samples taken in
between find it down. More than 30 s after boot that reads as a PMP that
never came up: every wake logged "PMP not running after 30 s", and the
sampling slowed to its give-up rate, holding the fallback limit (2688 MHz
on the J700's P cluster) until the next slow sample.

Restart the 30 s window at the suspend, as at boot. Jiffies don't count
the sleep, so the PMP gets 30 s after the wake.

Signed-off-by: Diljit Singh <hey@djdev.me>
…ebug link

A sleep woken by its own debug-link cut sleeps again as a dark wake, with
the link left down. When that second sleep was refused (an early wake
event), the full wake's rearm failed all 40 tries at the debug VDM: the
partner had dropped the PD contract, both ends sat at default USB power,
and the Debug USB never came back until a replug.

The debug VDM needs a contract. After a few failed tries, if the port has
none, do what the cut does when the contract doesn't come back: reset the
controller (Gaid), wait for the contract, at most three times, and set the
controller up again as after the cut before the next try.

Signed-off-by: Diljit Singh <hey@djdev.me>
After every firmware-driven sleep the Neo's USB-PD SPMI controller
raised its interrupt twice with nothing of ours to run, and the chained
handler reported a bad IRQ (bad_chained_irq dump for
apple_spmi_irq_handler). Read at those interrupts:
- the PD controllers' even lines, next to each odd one tipd uses, were
  pending: ACK 0xd1c00 and 0x1450 against enables 0x22000 and 0x28a0;
- another queue's response vector was pending in the vectors' word
  (0x80 next to ours), the sleep's own commands at the debug link's cut;
- tipd's own line was pending while still masked by the resume.

Nothing maps the first two, so nothing ever clears them. Track which
sources a driver has mapped and clear the pending ones nobody has, and
the other vectors' responses, as probe does for every source. A used
source pending while masked waits for its unmask and isn't reported.

Signed-off-by: Diljit Singh <hey@djdev.me>
The acks the chained handler writes are posted, and the parent is
unmasked as the handler returns, before they may have reached the
controller. Read the ACK block back first, so a cleared source can't
look pending to the parent again.

On the Neo this didn't remove the one bad_chained_irq that is left after
each firmware-driven sleep (down from two with stray sources cleared);
that one is still open.

Signed-off-by: Diljit Singh <hey@djdev.me>
@DjDeveloperr

Copy link
Copy Markdown
Contributor Author

Superseded by #1445 (merged as 2b05915); its changes are in integration/aurora. The PMP wait after a sleep is in drivers/cpufreq/apple-soc-cpufreq.c, the SPMI stray-interrupt handling in drivers/spmi/spmi-apple-controller.c, and the debug-link changes in drivers/usb/typec/tipd/.

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.

1 participant