From: Andrey Golovko <andrey.golovko@gmail.com>
To: Shenghao Ding <shenghao-ding@ti.com>, Kevin Lu <kevin-lu@ti.com>,
Baojun Xu <baojun.xu@ti.com>, Sen Wang <sen@ti.com>,
Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>, Jaroslav Kysela <perex@perex.cz>,
Takashi Iwai <tiwai@suse.com>
Cc: "Holalu Yogendra, Niranjan" <niranjan.hy@ti.com>,
Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>,
Vijendar Mukunda <Vijendar.Mukunda@amd.com>,
Antoine Monnet <antoine@montane.tech>,
Robin Everaars <robineveraars@pm.me>,
Ville Saarinen <wiza@saarinenkoti.fi>,
linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] ASoC: tas2783-sdw: power the Function up before preparing the port
Date: Thu, 13 Aug 2026 00:28:10 +0300 [thread overview]
Message-ID: <20260813001500.9218-1-andrey.golovko@gmail.com> (raw)
A Data Port cannot complete channel preparation while the SDCA Function
is powered down: the peripheral raises the channel's bit in
DPn_PrepareStatus and never clears it.
tas_sdw_hw_params() takes care of that for a stream that is being set
up, and the retry loop there says so - "ensure power on so that port
prepare succeeds". Port preparation, however, also happens on a stream
that is merely re-prepared, without hw_params() running again. That is
what userspace does after a suspend in which the peripheral lost power:
snd_pcm_prepare() reaches .prepare and sdw_prepare_stream(), the port is
prepared afresh, but PDE23 is still at the PS3 reset default because
nothing wrote it since the device came back.
The result is silence with no error anywhere. The codec sets
simple_ch_prep_sm, so sdw_prep_deprep_slave_port() skips the
NOT_PREPARED poll, and a port that never prepares is indistinguishable
from a healthy one.
Power the Function up in the PRE_PREP callback, immediately before the
PrepareCtrl write it already performs, so that preparation has what it
needs on every path that prepares a port.
Measured on an ASUS ProArt PX13 (AMD ACP7.0, two TAS2783): after s2idle
with ~100 s of S0i3 residency, DPn_PrepareStatus stays at the channel
mask and there is no audio; writing PDE23 PS0 and re-issuing the prepare
clears it within 1 ms and audio returns.
Signed-off-by: Andrey Golovko <andrey.golovko@gmail.com>
---
Measured on ASUS ProArt PX13 HN7306EAC (AMD ACP7.0, two TAS2783 at unique
0x8/0xB plus an rt721-sdca on link 1), on broonie/sound for-next.
Before, after an s2idle cycle in which the amplifiers really were powered
off, with no userspace workaround running:
PDE23 req=0x3 act=0x3 DPn_PrepareStatus 0x1 / 0x2 no audio
With this patch, same machine, an 8 min 51 s cycle with 526 s of S0i3
residency:
PDE23 req=0x0 act=0x0 DPn_PrepareStatus 0x0 / 0x0 audio works
Full analysis of the failure, including a reproduction that talks to the
peripheral directly and needs no ALSA at all, is in this thread:
https://lore.kernel.org/all/20260812192500.7714-1-andrey.golovko@gmail.com/
There I suggested the fix might instead belong in the AMD ACP driver,
which advertises SNDRV_PCM_INFO_RESUME on its SoundWire DMA PCMs. I have
since tested that and it does not help, for a reason worth recording:
after resume userspace calls snd_pcm_prepare(), which reaches .prepare
and sdw_prepare_stream() but never hw_params() again -- ALSA only
requires hw_params() after hw_free(). The port is therefore re-prepared
correctly, the bank flips and PrepareCtrl is written, while the Function
is still at PS3. No PCM flag can change that; the power-up has to sit on
a callback that runs whenever a port is prepared.
sound/soc/codecs/tas2783-sdw.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c
index c217da5fccdf..34689b9764c9 100644
--- a/sound/soc/codecs/tas2783-sdw.c
+++ b/sound/soc/codecs/tas2783-sdw.c
@@ -1259,6 +1259,7 @@ static int tas_port_prep(struct sdw_slave *slave, struct sdw_prepare_ch *prep_ch
enum sdw_port_prep_ops pre_ops)
{
struct device *dev = &slave->dev;
+ struct tas2783_prv *tas_dev = dev_get_drvdata(dev);
struct sdw_dpn_prop *dpn_prop;
u32 addr;
int ret;
@@ -1270,6 +1271,25 @@ static int tas_port_prep(struct sdw_slave *slave, struct sdw_prepare_ch *prep_ch
addr = SDW_DPN_PREPARECTRL(prep_ch->num);
switch (pre_ops) {
case SDW_OPS_PORT_PRE_PREP:
+ /*
+ * The Function has to be powered before the port can complete
+ * channel preparation. hw_params() does that when a stream is
+ * set up, but a stream that is only re-prepared - as userspace
+ * does after the peripheral lost power in S0i3 - does not go
+ * through hw_params() again, and the peripheral is back at its
+ * PS3 reset default. Power it up here, where it is needed.
+ */
+ scoped_guard(mutex, &tas_dev->pde_lock)
+ ret = regmap_write(tas_dev->regmap,
+ SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PDE23,
+ TAS2783_SDCA_CTL_REQ_POW_STATE, 0),
+ TAS2783_SDCA_POW_STATE_ON);
+ if (ret) {
+ dev_err(dev, "power up failed for port %d, err=%d\n",
+ prep_ch->num, ret);
+ return ret;
+ }
+
ret = sdw_write_no_pm(slave, addr, prep_ch->ch_mask);
if (ret)
dev_err(dev, "prep failed for port %d, err=%d\n",
base-commit: 6f6fb37f9f9a8ae88faa1b5b1978e57381488502
--
2.53.0
next reply other threads:[~2026-08-12 21:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-12 21:28 Andrey Golovko [this message]
2026-08-13 13:22 ` Mark Brown
2026-08-13 16:00 ` Mukunda,Vijendar
2026-08-13 16:45 ` Andrey Golovko
2026-08-13 21:19 ` Robin Everaars
2026-08-14 6:50 ` Andrey Golovko
2026-08-13 15:22 ` Robin Everaars
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=20260813001500.9218-1-andrey.golovko@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=niranjan.hy@ti.com \
--cc=perex@perex.cz \
--cc=pierre-louis.bossart@linux.dev \
--cc=robineveraars@pm.me \
--cc=sen@ti.com \
--cc=shenghao-ding@ti.com \
--cc=tiwai@suse.com \
--cc=wiza@saarinenkoti.fi \
/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
all inboxes | Powered by JetHome®