Repository navigation
drm: apple: audio: ask for audio elements like macOS, and balance runtime PM around the DMA stop - #276
drm: apple: audio: ask for audio elements like macOS, and balance runtime PM around the DMA stop#276nekolyanich wants to merge 3 commits into
Conversation
When the audio elements do not fit the buffer of the get_elements call, DCP returns them cut off at the buffer's end and reports a used size of 0. A Samsung TV behind a USB-C to HDMI adapter has 17312 bytes of elements, so with the 16 KiB we asked for, everything past 16 KiB was lost. macOS 13 asks for up to 256 KiB (max_size 0x40000 in the request, 0x43a0 used in the reply for this TV): do the same. Allocate the elements buffer and the call buffers with kvzalloc(), including the one in afk_service_call_timeout(), which every AFK service call goes through; it is only copied into the DMA buffers. Fixes: cb24343 ("gpu: drm: apple: Add DCP audio driver") Assisted-by: Claude:claude-opus-5-5 checkpatch Signed-off-by: nekolyanich <me@nekolyanich.com>
Trigger START returns -ENXIO before it takes the runtime PM reference
when no sink is connected. ALSA undoes a failed START with a STOP,
which put the reference all the same, so the usage count underflowed
("Runtime PM usage count underflow!", three times in one run on a
card whose display was off).
Remember whether the stream holds the reference, take it once in
START and put it in STOP only when it is held.
Fixes: f25cb50 ("drm: apple: audio: Implement runtime PM support")
Assisted-by: Claude:claude-opus-5-5 checkpatch
Signed-off-by: nekolyanich <me@nekolyanich.com>
…topped Trigger STOP put the runtime PM reference right after starting the asynchronous DMA terminate. Without autosuspend that suspends the device at once and powers its domain (ps_dpa1/ps_dpa2) down while SIO may still run DMA towards the DPA. SIO then crashed with "Shim DMA unavailable" and the TERMINATE timed out after it, taking DP audio on all outputs down until a reboot. On an M2 Pro with two DP sinks an earlier version of this change on a downstream tree took it from 4 of 4 boots to none in 11. Put the reference in sync_stop, after snd_dmaengine_pcm_sync_stop() waited for the terminate. ALSA calls sync_stop at the next hw_params, prepare or hw_free, at close, at system suspend and at disconnect, not right after the STOP, so after a drain, an xrun or a stop with the stream left open the DPA stays powered until then. Waiting inside trigger would also work (the PCM is nonatomic), but sync_stop is the hook ALSA has for it, as in the AOP audio driver. sync_stop runs outside the stream lock: test and clear pm_held under it. The check in START now matters, since a START can follow a failed one before sync_stop ran. Fixes: f25cb50 ("drm: apple: audio: Implement runtime PM support") Assisted-by: Claude:claude-opus-5-5 checkpatch Signed-off-by: nekolyanich <me@nekolyanich.com>
|
@nekolyanich thanks for this. I tested it natively on a Mac mini M1 (j274), and it works. Setup:
One thing you might run into: with PipeWire's default settings, mpv stayed silent on this PR alone. PipeWire asked for 128 periods, SIO has only 64 descriptor slots (one per period), so START failed with Tested-by: Thomas Glanzmann thomas@glanzmann.de |
|
Thanks for testing on the M1, and for #277. We hit the same SIO limit and carry the same cap (16 periods) on our downstream tree, so +1 for #277. Some other things we found on an M2 Pro (j416s, 13.5 firmware) with a Samsung TV on a USB-C to HDMI adapter and a Dell over Thunderbolt. Code will follow once each is verified:
|
|
All three commits are ported in review/pr276-integration-t3094-v3, head fe5d0c4, preserving original authorship and sign-offs. The port keeps the native T6030 path and sinkless behavior. Generic sync_stop cancels the sinkless work and drains DMA before clearing/releasing the held PM reference under the stream lock. The larger elements buffer keeps its matching allocation/free pairs. The fresh extracted PM/DMA positive control and three runtime mutants pass. On integration/aurora at 421e314 with shared #438 and #456, DCP is PASS (63/63). KUnit has 905 passes and 1 policy skips. Universal WERROR is PASS; Fedora-base WERROR is PASS. Software gates pass; hardware and shared #438/#456 review pending. The operator reports #456 passed all 63 host groups with stock make 3.81 and GNU Make; this worker did not rerun native macOS on the assembled base. Hardware still needed: M1 Pro/M2 stop, unplug, sinkless and runtime PM; Neo audio regression. |
|
Tested on J416s (M2 Pro),
Runs and this summary were prepared with Claude (Opus 5.5); counts checked against the logs. |
Three fixes to the DCP audio driver, found while bringing up DP and HDMI audio on an M2 Pro (j416s) with a Samsung TV on a USB-C to HDMI adapter and a Dell monitor over Thunderbolt.
Commits:
drm: apple: audio: ask for up to 256 KiB of audio elements, as macOS: when the audio elements don't fit the buffer of theget_elementscall, DCP returns them cut off at the buffer's end and reports a used size of 0. The TV's elements are 17312 bytes, so with the 16 KiB we asked for, everything past 16 KiB was lost; the stereo formats happen to sit in the first part, so the TV still got a usable card. macOS 13 asks for up to 256 KiB (in a hypervisor trace of macOS with the same TV:max_size0x40000 in the request,used_size0x43a0 in the reply). The elements buffer and the call buffers, including the one inafk_service_call_timeout(), are now allocated withkvzalloc().drm: apple: audio: balance the runtime PM reference of a failed START: trigger START returns-ENXIObefore it takes the runtime PM reference when no sink is connected, and ALSA undoes a failed START with a STOP, which put the reference anyway: "Runtime PM usage count underflow!". The stream now remembers whether it holds the reference.drm: apple: audio: drop the runtime PM reference only after the DMA stopped: trigger STOP put the reference right after starting the asynchronous DMA terminate. Without autosuspend the DPA's power domain (ps_dpa1/ps_dpa2) then went down while SIO could still run DMA towards it, SIO crashed with "Shim DMA unavailable", the TERMINATE timed out, and DP audio was gone on all outputs until a reboot. The reference is now put insync_stop, aftersnd_dmaengine_pcm_sync_stop()waited for the terminate; it uses the same hook as ASoC/dmaengine: wait for stopped capture streams (t8140-aop-audio sync_stop, apple-admac synchronize) #259 for the AOP audio. ALSA callssync_stopat the next hw_params, prepare or hw_free, at close, at system suspend and at disconnect, so after a drain or an xrun the DPA now stays powered until then.Testing: MacBook Pro 16" M2 Pro (j416s), DCP firmware 13.5. Samsung TV on a USB-C to HDMI adapter (DP alt mode,
dcpext0) and a Dell U2725QE over Thunderbolt (DP IN tunnel,dcpext1). Each kernel isaurora-wip3b2bd35aplus the commits shown, run under the m1n1 hypervisor. Two things differ from your setup:atc0out of the DCP routes, because m1n1 keeps that port for the hypervisor's USB link; without it the kernel waits forever indeferred_probe_initcall;An initramfs plays 6 s of silence (S24_LE, 2 ch, 48 kHz) on each DCP card and logs the PCM state every second.
aurora-wipused_size0 (1 run)The SIO crash that commit 3 fixes did not show under the hypervisor on any of these kernels. It showed natively on our own tree (Asahi fairydust with the USB4 series backported): 4 of 4 boots before an earlier version of this change, none in 11 after. The code it changes is the same in
aurora-wip.Not fixed here: the TV goes dark after DCP's own replug. On every run where the TV started (15 of 15), DCP refuses the first audio start on this TV ("Restarting interfaces with reason - Capabilities changed") and replugs the display itself; macOS gets one such refusal on this TV too and carries on after the replug. On
connected:0, fbdev turns the CRTC off, and the Type-C branch ofdcp_poweroff()deasserts the HPD and callsdcp_dptx_disconnect()(DPTX DEACTIVATE). DCP's replug then has nothing to come back on, and the TV stays dark. Stack, from a kernel with a debugdump_stack()there:On our tree
dcp_poweroff()leaves the DPTX port alone, and DCP brings the TV back 2.2 s later. I'm not sure what the right change is with your Type-C route logic, so I'm leaving it out of this PR. #275 (relinking a Type-C sink that DCP dropped while it still asserts HPD) may well cover this case; I haven't tried it yet. So far I haven't heard sound from the TV onaurora-wip, only seen its elements and the Dell's stream.Not tested: natively on
aurora-wip, other Macs, other sinks, the DCP 12.3 firmware command table.🤖 Generated with Claude Code