From: Andrey Golovko <andrey.golovko@gmail.com>
To: Antoine Monnet <antoine@montane.tech>, 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: Re: ASoC: tas2783-sdw: calibration firmware not re-downloaded after s2idle resume (AMD ACP SoundWire, ASUS ProArt PX13)
Date: Mon, 27 Jul 2026 11:13:29 +0300 [thread overview]
Message-ID: <2d59f17b67d3886a3085f0da8c8850f3@gmail.com> (raw)
In-Reply-To: <c66ae00a-e878-4af0-a05a-272e9574eaa5@montane.tech>
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
next prev parent reply other threads:[~2026-07-27 8:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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=2d59f17b67d3886a3085f0da8c8850f3@gmail.com \
--to=andrey.golovko@gmail.com \
--cc=Vijendar.Mukunda@amd.com \
--cc=antoine@montane.tech \
--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 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.