Re: ASoC: tas2783-sdw: port prepare never completes after S0i3, no audio and no error (AMD ACP7.0, ASUS ProArt PX13)
Andrey Golovko <[email protected]>
| Newsgroups | org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi Niranjan, Pierre-Louis, thanks to both - answers and new data inline. Pierre-Louis wrote: > Just to be clear: are you referring to a scenario where audio playback > is on-going, the device does a system suspend during the audio playback > due to a user request, and on resume audio is supposed to restart > playing? Not necessarily on-going playback - that's the point that makes this hit ordinary users. PipeWire keeps the PCM substream open the whole session, so the substream survives the suspend regardless of whether anything was audibly playing. After resume, even a stream started *fresh* by an application plays into that surviving substream and is silent. The only way to get sound back is to force the substream through hw_free + hw_params (I cycle the card profile, which PipeWire translates into exactly that). So the reproduction is deterministic and needs no aplay-in-background race: boot, let PipeWire open the device, systemctl suspend for >= 1 min (enough for amd_pmc to report real S0i3 residency; without residency the bug does not reproduce), resume, start any playback. Silent every time here. > It could be that the use of the port_prep callback is restricted to the > initial stream setup. I am not sure if that stream callback is invoked a > second time after a suspend-resume cycle I can answer that with a trace rather than a guess, with one caveat: stock ps-sdw-dma.c advertises SNDRV_PCM_INFO_RESUME, so a plain resume takes TRIGGER_RESUME and skips the prepare path entirely - no stream callbacks at all. With a local patch dropping INFO_RESUME (so userspace does a full snd_pcm_prepare recovery), the resume-spanning ftrace shows the complete sequence running after resume: sdw_prepare_stream -> sdw_prep_deprep_slave_ports -> tas_port_prep() invoked again, 4 calls (2 amps x 2 callbacks), DPn_PrepareCtrl written with the right masks, then enable. So the callback *is* invoked on the recovery path - and the amps are still silent. The one thing that separates every silent case from every working case in my traces is the de-prepare: the working path (hw_free) writes DPn_PrepareCtrl = 0 first, then a fresh prepare writes 3. The silent path re-writes 3 over 3. After the device has lost power and been re-initialized (SW_RESET + firmware re-download on re-attach), a rewrite of the same value evidently does not re-arm anything; the 0 -> 3 edge does. Niranjan wrote: > The device expects the DPn_PrepareCtrl bits to be set to be functional - > but doesn't update DPn_PrepareStatus. Thanks, that explains the design - I'll withdraw the "port prepare never completes" framing then, since it leaned on reading DPn_PrepareStatus, and per your description those bits are not to be interpreted in Simplified_CP_SM. One empirical note, for what it's worth: on this hardware 0x104 is not static. Across all my dumps, on both amplifiers, it reads 0x3 in every silent state and 0x0 in every working state, tracking the audible state exactly. I'm not suggesting polling it - just that on this part the register does reflect something about the port state. Which leaves the practical question for TI: After the amplifier loses power while the manager is power-gated (attach as UNINITIALIZED, SW_RESET, firmware re-download), what does the device need before a port prepare takes effect again? Empirically writing DPn_PrepareCtrl = 0 and then 3 works, while writing 3 alone does not. If the 0 -> 3 sequence is genuinely required, where should it live - tas_port_prep() unconditionally de-preparing before preparing, or the codec driver de-preparing its ports as part of the re-attach re-init? If TI can confirm the required sequence I'm happy to write and test the patch on this hardware - I already have the register dumps and traces automated. Thanks, Andrey