Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Antoine Monnet <antoine@montane.tech>
To: linux-sound@vger.kernel.org
Cc: shenghao-ding@ti.com, kevin-lu@ti.com, baojun.xu@ti.com,
	broonie@kernel.org, lgirdwood@gmail.com,
	Vijendar.Mukunda@amd.com, vkoul@kernel.org,
	yung-chuan.liao@linux.intel.com, pierre-louis.bossart@linux.dev,
	linux-kernel@vger.kernel.org
Subject: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13)
Date: Sun, 19 Jul 2026 02:22:45 +0200	[thread overview]
Message-ID: <c66ae00a-e878-4af0-a05a-272e9574eaa5@montane.tech> (raw)

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


             reply	other threads:[~2026-07-19  0:22 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-19  0:22 Antoine Monnet [this message]
2026-07-27  8:13 ` ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13) 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c66ae00a-e878-4af0-a05a-272e9574eaa5@montane.tech \
    --to=antoine@montane.tech \
    --cc=Vijendar.Mukunda@amd.com \
    --cc=baojun.xu@ti.com \
    --cc=broonie@kernel.org \
    --cc=kevin-lu@ti.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=shenghao-ding@ti.com \
    --cc=vkoul@kernel.org \
    --cc=yung-chuan.liao@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox