* ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) @ 2026-07-19 0:22 Antoine Monnet 2026-07-27 8:13 ` Andrey Golovko 0 siblings, 1 reply; 7+ messages in thread From: Antoine Monnet @ 2026-07-19 0:22 UTC (permalink / raw) To: linux-sound Cc: shenghao-ding, kevin-lu, baojun.xu, broonie, lgirdwood, Vijendar.Mukunda, vkoul, yung-chuan.liao, pierre-louis.bossart, linux-kernel Hi, On an ASUS ProArt PX13 (HN7306, Ryzen AI Max / "Strix Halo") with two TAS2783 SoundWire smart-amps on the AMD ACP SoundWire controller, internal-speaker playback works after a cold boot but fails permanently after a single s2idle suspend/resume cycle. From then on every playback attempt logs: slave-tas2783 sdw:0:1:0102:0000:01:8: error playback without fw download slave-tas2783 sdw:0:1:0102:0000:01:8: ASoC error (-22): at snd_soc_dai_hw_params() on tas2783-codec and userspace (PipeWire) drops to a dummy sink. Only a full reboot restores audio. Environment ----------- Machine : ASUS ProArt PX13, HN7306 (Ryzen AI Max, "Strix Halo") Distro : Debian 13 (trixie) 13.6 Kernel : 7.0.13+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 7.0.13-1~bpo13+1 ACP : 0000:c4:00.5 Audio Coprocessor [1022:15e2] rev 70, subsystem ASUSTeK [1043:1714], driver snd_pci_ps Codecs : 2x TAS2783 (SoundWire link 1, slaves 0x8 / 0xB) + rt721-sdca jack sdw:0:1:0102:0000:01:8, sdw:0:1:0102:0000:01:b, sdw:0:1:025d:0721:01 Card : 1 [amdsoundwire]: amd-soundwire - ASUSTeKCOMPUTERINC.-ProArtPX13HN7306EAC-1.0-HN7306EAC Note on the driver build: Debian ships sound/soc/codecs/tas2783-sdw.c but does not set CONFIG_SND_SOC_TAS2783_SDW, so I built the *unmodified* in-tree driver as an out-of-tree module (DKMS) from the matching 7.0.13 kernel source. The code is upstream and the defect is visible by inspection in current mainline too (checked against the 7.1.3 tree — the resume path is unchanged). Analysis (root cause) --------------------- The amp's calibration/DSP firmware is downloaded once, via request_firmware_nowait() inside tas_io_init(), which is gated by ->hw_init and only runs on a SoundWire UNATTACHED->ATTACHED transition (tas_update_status()), setting ->fw_dl_success on completion. During s2idle the SoC powers down and the TAS2783 DSP loses that firmware. The system-resume callback tas2783_sdca_dev_resume() only performs regcache_sync(); it does not re-download the firmware, and the downloaded DSP coefficients are not part of the regmap cache. ->hw_init stays true, so tas_io_init() (hence request_firmware_nowait()) is never called again, ->fw_dl_success stays false, and the next hw_params() bails out with "error playback without fw download" (-EINVAL). What I tried (none recover it; all consistent with the above) ------------------------------------------------------------ - ACP PCI reset (unbind/bind snd_pci_ps 0000:c4:00.5): the card is fully torn down and recreated (/proc/asound/cards goes 1 -> 0 -> 1), yet firmware is still not downloaded. - Driver-level unbind/rebind of both amp SoundWire devices: fresh probe, no firmware download. - Full module reload (modprobe -r snd_soc_tas2783_sdw after ACP teardown, then reload) + ACP rebind: still no firmware. - Only a cold reboot re-initializes the amp DSP and restores audio. So neither a bus re-enumeration nor a fresh driver probe re-arms the download in practice; the one-shot ->hw_init gate plus a resume path that only does regcache_sync() leaves the DSP permanently firmware-less until a power cycle. Suggested fix ------------- On system resume (and on any re-enumeration where the DSP may have lost state) the driver should re-run the firmware-download path rather than rely on regcache_sync() — e.g. clear ->hw_init / ->fw_dl_success and re-trigger tas_io_init() / request_firmware_nowait() from tas2783_sdca_dev_resume(), or gate the (re)download on DSP power state instead of a one-shot ->hw_init flag. Reproduce --------- 1. Cold boot; confirm internal speakers play. 2. systemctl suspend (s2idle); wake. 3. Play audio -> "error playback without fw download"; sink is dummy. 4. ACP reset / driver rebind / module reload do not recover; reboot does. Happy to test patches on this hardware. Thanks, Antoine ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) 2026-07-19 0:22 ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) Antoine Monnet @ 2026-07-27 8:13 ` Andrey Golovko 2026-07-27 9:04 ` Mukunda,Vijendar 2026-07-27 13:44 ` Mark Brown 0 siblings, 2 replies; 7+ messages in thread From: Andrey Golovko @ 2026-07-27 8:13 UTC (permalink / raw) To: Antoine Monnet, linux-sound Cc: shenghao-ding, kevin-lu, baojun.xu, broonie, lgirdwood, Vijendar.Mukunda, vkoul, yung-chuan.liao, pierre-louis.bossart, linux-kernel Hi Antoine, Same machine here (ASUS ProArt PX13 HN7306EAC, ACP rev 0x70, RT721 + 2x TAS2783 on link 1). First, the reason you never saw a re-download at all: on <= v7.2-rc3 the peripherals do not re-attach after s2idle, so tas_update_status() is never called with ATTACHED and nothing downstream of it can run. That is a separate ACP bug, fixed in v7.2-rc4 by 5893013efabb ("ASoC: amd: ps: disable MSI on resume in ACP PCI driver") Details in my reply on your other thread [1]. With that fix in place, the firmware IS re-downloaded on every resume and the one-shot ->hw_init gate is not the blocker: tas_update_status() sets hw_init = false on UNATTACHED, so the ATTACHED transition re-runs tas_io_init() and request_firmware_nowait() as intended. I confirmed the download really happens over the wire with ftrace: ~81k calls to amd_sdw_send_cmd_get_resp() during a single resume, i.e. an honest full re-download of both amps, not a cached no-op. One trap worth naming, since it fooled me for a while: in the resume path printk timestamps make the download look impossible (32 KB in ~150 us, 5 ns/byte), because sched_clock is not running yet that early. Do not trust the log deltas there - use ftrace. So the symptom you filed is real, but the mechanism is elsewhere. On this board, after a resume with genuine deep S0i3 residency (51 s of a 57 s sleep, per /sys/kernel/debug/amd_pmc/s0ix_stats), all three peripherals are Attached, the firmware is reloaded, every log line is clean - and the speakers are silent. Root cause #1: stale regmap cache --------------------------------- In tas_update_status(), on the UNATTACHED -> ATTACHED transition, the driver does: regcache_cache_only(tas_dev->regmap, false); regcache_sync(tas_dev->regmap); /* then */ return tas_io_init(&slave->dev, slave); Two problems: the sync runs *before* tas_io_init(), which performs a software reset and thus wipes whatever was just written; and there is no regcache_mark_dirty(), so the sync is close to a no-op to begin with. The cache therefore survives the power cycle claiming that the DAPM power/unmute bits and the SDCA PDE entity are already at their target values. Every subsequent regmap_update_bits() - amp power-up from DAPM, PDE programming at stream start - sees "no change" and skips the write. The amplifier stays powered down and nothing in the log complains. Consistent with that: unbind/rebind of slave-tas2783 (fresh cache) restores sound immediately, while toggling mixer controls does not. What does not work as a fix: adding regcache_mark_dirty() + a real regcache_sync() after tas_io_init(). This regmap is SDW-MBQ (devm_regmap_init_sdw_mbq_cfg) with per-register mbq_size, and the cache also holds non-MBQ registers written during init, so regcache_sync() fails with -EINVAL on the first such register, and the failure then also breaks probe ("Update Slave status failed: -22"). A full sync is simply not usable for this regmap. What does work here: drop the stale cache instead of syncing it, i.e. regcache_drop_region(0, UINT_MAX) before tas_io_init() when the device re-attaches uninitialized, so the following update_bits() calls read real hardware. Side effect: user-set controls fall back to hardware defaults after a resume, which seems the lesser evil versus a silent amp. I will send this as a proper patch. Note for Mark/TI: it will be based on top of 0d6b2d6f93a6 ("ASoC: codecs: tas2783-sdw: Propagate regcache_sync() errors") currently in for-next, which touches the same two call sites. Root cause #2: ACP SoundWire DMA config not reprogrammed on recovery -------------------------------------------------------------------- Even with the cache fixed, sound only returns after the PCM is fully recreated (pactl profile off/on), not after a plain userspace resume. sound/soc/amd/ps/ps-sdw-dma.c advertises SNDRV_PCM_INFO_RESUME, so userspace issues TRIGGER_RESUME (or prepare without hw_params), while the ring-buffer registers (RINGBUFADDR/RINGBUFSIZE, watermark, IRQ masks) are only programmed in hw_params. The DMA is then started with unprogrammed registers: silence, followed by an XRUN. Intel does not set INFO_RESUME on SoundWire for exactly this reason. Dropping INFO_RESUME plus reprogramming the DMA config from .prepare still does not fully restore audio here, so something else is lost across the power gate on the ACP/manager side. I will post that part separately, with traces, addressed to the AMD folks - it does not belong in this codec thread. Happy to test patches on this hardware. [1] https://lore.kernel.org/all/466a905d-8203-46d2-bfe4-a3b3f9b5d68b@montane.tech/ Thanks, Andrey ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) 2026-07-27 8:13 ` Andrey Golovko @ 2026-07-27 9:04 ` Mukunda,Vijendar 2026-07-27 9:32 ` Andrey Golovko ` (2 more replies) 2026-07-27 13:44 ` Mark Brown 1 sibling, 3 replies; 7+ messages in thread From: Mukunda,Vijendar @ 2026-07-27 9:04 UTC (permalink / raw) To: Andrey Golovko, Antoine Monnet, linux-sound Cc: shenghao-ding, kevin-lu, baojun.xu, broonie, lgirdwood, vkoul, yung-chuan.liao, pierre-louis.bossart, linux-kernel, Dommati, Sunil-kumar, Syed Saba Kareem, Venkata prasad Potturu On 27/07/26 13:43, Andrey Golovko wrote: > oot cause #2: ACP SoundWire DMA config not reprogrammed on recovery > -------------------------------------------------------------------- > Even with the cache fixed, sound only returns after the PCM is fully > recreated (pactl profile off/on), not after a plain userspace resume. > sound/soc/amd/ps/ps-sdw-dma.c advertises SNDRV_PCM_INFO_RESUME, so > userspace issues TRIGGER_RESUME (or prepare without hw_params), while the > ring-buffer registers (RINGBUFADDR/RINGBUFSIZE, watermark, IRQ masks) are > only programmed in hw_params. The DMA is then started with unprogrammed > registers: silence, followed by an XRUN. Intel does not set INFO_RESUME > on SoundWire for exactly this reason. > > Dropping INFO_RESUME plus reprogramming the DMA config from .prepare > still does not fully restore audio here, so something else is lost across > the power gate on the ACP/manager side. I will post that part separately, > with traces, addressed to the AMD folks - it does not belong in this > codec thread. ++ @Andrey Golovko: restoring the dma ring buffer reigsters, pte programming along with re-enabling irq mask will be done in acp70_restore_sdw_dma_config() function which will be invoked during resume sequence. Could you please create Bugzilla ticket and attach dmesg logs? ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) 2026-07-27 9:04 ` Mukunda,Vijendar @ 2026-07-27 9:32 ` Andrey Golovko 2026-07-27 9:32 ` Andrey Golovko 2026-07-27 9:55 ` Andrey Golovko 2 siblings, 0 replies; 7+ messages in thread From: Andrey Golovko @ 2026-07-27 9:32 UTC (permalink / raw) To: Mukunda,Vijendar, Antoine Monnet, linux-sound Cc: shenghao-ding, kevin-lu, baojun.xu, broonie, lgirdwood, vkoul, yung-chuan.liao, pierre-louis.bossart, Mario Limonciello, linux-kernel Thanks for the quick response. > restoring the dma ring buffer reigsters, pte programming along with > re-enabling irq mask will be done in acp70_restore_sdw_dma_config() > function which will be invoked during resume sequence. You are right, and my earlier description of that part was wrong - I apologise. acp63_sdw_pcm_resume() is the SYSTEM_SLEEP resume callback and it does exactly that for every live substream, and it has been there since v7.2-rc1. My claim that the ring buffer registers are only programmed in hw_params was incorrect. I have since measured it on the hardware instead of reading code, and the measurements confirm your point: the ACP side is fine, and the audio is lost somewhere else entirely. Setup: ASUS ProArt PX13 HN7306EAC, ACP rev 0x70, two TAS2783 + RT721 on link 1, v7.2-rc4 plus 5893013efabb. One s2idle cycle of 147 s with 140 s of S0i3 residency, i.e. a real power gate. After resume the speakers are silent, with no error anywhere in the log. 1) ACP registers during silent playback versus during working playback (after the card profile is cycled, which restores audio): I dumped ring buffer address/size, FIFO address/size, DMA size, watermark, stream enable and the SoundWire manager block - 72 of 78 registers are bit-identical. The only differences are ACP_EXTERNAL_INTR_CNTL, where the silent capture has the extra PDM_DMA_INTR_MASK bit because the mics happened to be open, and the last immediate command/response pair. So acp70_restore_sdw_dma_config() does its job. 2) The DMA is running while silent. Sampling ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR every 500 ms: +96064, +96000, +96064, +96064, +96000 bytes 96000 bytes per 500 ms = 192000 B/s = 48 kHz x 2 ch x 2 bytes, exactly nominal. The ACP fetches the buffer and feeds the SoundWire FIFO for the entire time the speakers produce nothing. 3) The difference is on the peripherals. Dumping /sys/kernel/debug/soundwire/master-0-1/sdw:*/registers during playback, silent versus working, the whole difference across all three peripherals is one register, on both amplifiers: DP1 0x104 (DPn_PrepareStatus): silent = 0x3 working = 0x0 with DPn_PrepareCtrl = 0x3 and DPn_ChannelEn = 0x3 in both cases. Since a set bit there means "not prepared" (the core polls for NOT_PREPARED == 0 in sdw_prep_deprep_slave_ports()), both amps sit with their port unprepared while the manager streams at them. Nothing notices, because tas2783-sdw declares simple_ch_prep_sm, so the core skips its write-and-poll and the codec's own tas_port_prep() writes DPn_PrepareCtrl without ever checking the status. I have sent the details of that part to the TI folks in a separate thread so as not to derail this one. I will file a Bugzilla ticket with the full dmesg (dyndbg enabled), the register dumps from both states and the DMA counter trace, and post the number here. One question while I have your attention: given that acp70_restore_sdw_dma_config() restores the DMA configuration on resume, is SNDRV_PCM_INFO_RESUME on the SoundWire DMA PCM intended? Intel does not set it for SoundWire, and with it userspace can issue TRIGGER_RESUME and skip prepare entirely. On this board that path leads to the silent state described above, though after these measurements I no longer think the flag is the root cause. Thanks, Andrey ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) 2026-07-27 9:04 ` Mukunda,Vijendar 2026-07-27 9:32 ` Andrey Golovko @ 2026-07-27 9:32 ` Andrey Golovko 2026-07-27 9:55 ` Andrey Golovko 2 siblings, 0 replies; 7+ messages in thread From: Andrey Golovko @ 2026-07-27 9:32 UTC (permalink / raw) To: Mukunda,Vijendar, Antoine Monnet, linux-sound Cc: shenghao-ding, kevin-lu, baojun.xu, broonie, lgirdwood, vkoul, yung-chuan.liao, pierre-louis.bossart, Mario Limonciello, linux-kernel Thanks for the quick response. > restoring the dma ring buffer reigsters, pte programming along with > re-enabling irq mask will be done in acp70_restore_sdw_dma_config() > function which will be invoked during resume sequence. You are right, and my earlier description of that part was wrong - I apologise. acp63_sdw_pcm_resume() is the SYSTEM_SLEEP resume callback and it does exactly that for every live substream, and it has been there since v7.2-rc1. My claim that the ring buffer registers are only programmed in hw_params was incorrect. I have since measured it on the hardware instead of reading code, and the measurements confirm your point: the ACP side is fine, and the audio is lost somewhere else entirely. Setup: ASUS ProArt PX13 HN7306EAC, ACP rev 0x70, two TAS2783 + RT721 on link 1, v7.2-rc4 plus 5893013efabb. One s2idle cycle of 147 s with 140 s of S0i3 residency, i.e. a real power gate. After resume the speakers are silent, with no error anywhere in the log. 1) ACP registers during silent playback versus during working playback (after the card profile is cycled, which restores audio): I dumped ring buffer address/size, FIFO address/size, DMA size, watermark, stream enable and the SoundWire manager block - 72 of 78 registers are bit-identical. The only differences are ACP_EXTERNAL_INTR_CNTL, where the silent capture has the extra PDM_DMA_INTR_MASK bit because the mics happened to be open, and the last immediate command/response pair. So acp70_restore_sdw_dma_config() does its job. 2) The DMA is running while silent. Sampling ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR every 500 ms: +96064, +96000, +96064, +96064, +96000 bytes 96000 bytes per 500 ms = 192000 B/s = 48 kHz x 2 ch x 2 bytes, exactly nominal. The ACP fetches the buffer and feeds the SoundWire FIFO for the entire time the speakers produce nothing. 3) The difference is on the peripherals. Dumping /sys/kernel/debug/soundwire/master-0-1/sdw:*/registers during playback, silent versus working, the whole difference across all three peripherals is one register, on both amplifiers: DP1 0x104 (DPn_PrepareStatus): silent = 0x3 working = 0x0 with DPn_PrepareCtrl = 0x3 and DPn_ChannelEn = 0x3 in both cases. Since a set bit there means "not prepared" (the core polls for NOT_PREPARED == 0 in sdw_prep_deprep_slave_ports()), both amps sit with their port unprepared while the manager streams at them. Nothing notices, because tas2783-sdw declares simple_ch_prep_sm, so the core skips its write-and-poll and the codec's own tas_port_prep() writes DPn_PrepareCtrl without ever checking the status. I have sent the details of that part to the TI folks in a separate thread so as not to derail this one. I will file a Bugzilla ticket with the full dmesg (dyndbg enabled), the register dumps from both states and the DMA counter trace, and post the number here. One question while I have your attention: given that acp70_restore_sdw_dma_config() restores the DMA configuration on resume, is SNDRV_PCM_INFO_RESUME on the SoundWire DMA PCM intended? Intel does not set it for SoundWire, and with it userspace can issue TRIGGER_RESUME and skip prepare entirely. On this board that path leads to the silent state described above, though after these measurements I no longer think the flag is the root cause. Thanks, Andrey ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) 2026-07-27 9:04 ` Mukunda,Vijendar 2026-07-27 9:32 ` Andrey Golovko 2026-07-27 9:32 ` Andrey Golovko @ 2026-07-27 9:55 ` Andrey Golovko 2 siblings, 0 replies; 7+ messages in thread From: Andrey Golovko @ 2026-07-27 9:55 UTC (permalink / raw) To: Mukunda,Vijendar, Antoine Monnet, linux-sound Cc: shenghao-ding, kevin-lu, baojun.xu, broonie, lgirdwood, vkoul, yung-chuan.liao, pierre-louis.bossart, Mario Limonciello, linux-kernel > Could you please create Bugzilla ticket and attach dmesg logs? Filed as https://bugzilla.kernel.org/show_bug.cgi?id=221798 and added you to the CC list. Attached there: the full kernel log of the boot containing the cycle, the ACP register dumps from the silent and the working state plus their diff (72 of 78 registers identical), the SoundWire peripheral register dumps from both states plus their diff (the only difference being DP1 DPn_PrepareStatus 0x3 vs 0x0 on both amplifiers), and the DMA position counter trace showing the ACP feeding the FIFO at the nominal 192000 B/s while the speakers are silent. Also cross-referenced there: bug 221584, which is the earlier "peripherals stay unattached after s0i3" report on the same machine. That one is fixed by your 5893013efabb in v7.2-rc4; it has not been picked up for 7.1.y, where at least two more users are still hitting it. Sorry about the duplicate copy of my previous mail - a command run twice. Thanks, Andrey ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) 2026-07-27 8:13 ` Andrey Golovko 2026-07-27 9:04 ` Mukunda,Vijendar @ 2026-07-27 13:44 ` Mark Brown 1 sibling, 0 replies; 7+ messages in thread From: Mark Brown @ 2026-07-27 13:44 UTC (permalink / raw) To: Andrey Golovko Cc: Antoine Monnet, linux-sound, shenghao-ding, kevin-lu, baojun.xu, lgirdwood, Vijendar.Mukunda, vkoul, yung-chuan.liao, pierre-louis.bossart, linux-kernel [-- Attachment #1: Type: text/plain, Size: 684 bytes --] On Mon, Jul 27, 2026 at 11:13:29AM +0300, Andrey Golovko wrote: > What does work here: drop the stale cache instead of syncing it, i.e. > regcache_drop_region(0, UINT_MAX) before tas_io_init() when the device > re-attaches uninitialized, so the following update_bits() calls read real > hardware. Side effect: user-set controls fall back to hardware defaults > after a resume, which seems the lesser evil versus a silent amp. That's buggy since it will throw away all the userspace configuration done through controls that map directly onto registers, without notifications too. The suspend path should be bringing the driver down to idle and then that should be undone on resume. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-27 13:44 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-19 0:22 ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) Antoine Monnet 2026-07-27 8:13 ` Andrey Golovko 2026-07-27 9:04 ` Mukunda,Vijendar 2026-07-27 9:32 ` Andrey Golovko 2026-07-27 9:32 ` Andrey Golovko 2026-07-27 9:55 ` Andrey Golovko 2026-07-27 13:44 ` Mark Brown
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.