All of lore.kernel.org
 help / color / mirror / Atom feed
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>,
	linux-sound@vger.kernel.org
Cc: Mark Brown <broonie@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Vinod Koul <vkoul@kernel.org>,
	Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>,
	Bard Liao <yung-chuan.liao@linux.intel.com>,
	Vijendar Mukunda <Vijendar.Mukunda@amd.com>,
	Mario Limonciello <superm1@kernel.org>,
	Antoine Monnet <antoine@montane.tech>,
	linux-kernel@vger.kernel.org
Subject: ASoC: tas2783-sdw: port prepare never completes after S0i3, no audio and no error (AMD ACP7.0, ASUS ProArt PX13)
Date: Mon, 27 Jul 2026 12:33:20 +0300	[thread overview]
Message-ID: <b1bc21c8a403fe15e742b6a6ff30b27f@gmail.com> (raw)

Hi,

On an ASUS ProArt PX13 HN7306EAC (Ryzen AI MAX+ 395, AMD ACP rev 0x70,
two TAS2783 at unique_id 0x8/0xB plus RT721 on SoundWire link 1), audio
is silent after resume from s2idle whenever the platform actually reaches
S0i3. Playback runs with no error whatsoever - no XRUN at first, no
prepare failure, no bus error - and the speakers stay quiet until the PCM
is fully torn down and recreated.

This is with v7.2-rc4 plus 5893013efabb ("ASoC: amd: ps: disable MSI on
resume in ACP PCI driver"), which is what makes the peripherals re-attach
at all on this board [1], and with a local fix that drops the stale
tas2783 regcache on re-attach [2]. Both are necessary here; neither is
sufficient.

I measured where the audio stops, and the answer is not where I expected.

1. The ACP side is healthy
--------------------------
I dumped the ACP registers that the driver programs (ring buffer address
and size, FIFO address and size, DMA size, watermark, stream enable, plus
the SoundWire manager block) during actual playback, once in the silent
state after resume and once after the workaround restored audio.

72 of 78 registers are bit-identical. The only differences are
ACP_EXTERNAL_INTR_CNTL (one extra bit, 0x10000 = PDM_DMA_INTR_MASK, i.e.
the digital mics, unrelated to this stream) and the last immediate
command/response pair on the bus.

That is expected: acp63_sdw_pcm_resume() reprograms the PTE, the ring
buffer, the watermark and the DMA interrupt masks for every live
substream on system resume. The ACP DMA configuration is restored
correctly.

2. The DMA is running at the correct rate while silent
------------------------------------------------------
Sampling ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR every 500 ms during silent
playback:

  0x000002FBF880  +96064
  0x000002FD6F80  +96000
  0x000002FEE6C0  +96064
  0x000003005E00  +96064
  0x00000301D500  +96000

96000 bytes per 500 ms = 192000 B/s = 48000 Hz x 2 ch x 2 bytes, exactly
nominal. The ACP is fetching the buffer and feeding the SoundWire FIFO
the whole time the speakers are silent.

3. The peripheral port never finishes preparing
-----------------------------------------------
Dumping /sys/kernel/debug/soundwire/master-0-1/sdw:*/registers during
playback, silent state versus working state, the entire difference across
all three peripherals is two registers - and it is the same register on
both amplifiers:

  DP1 0x104 (DPn_PrepareStatus):  silent = 0x3   working = 0x0

with DPn_PrepareCtrl (0x105) = 0x3 and DPn_ChannelEn = 0x3 in both cases.
(The third difference is SCP_Int1 on one amp, i.e. transient interrupt
status.)

Per the core's own reading of that register - "Poll for NOT_PREPARED==0"
in sdw_prep_deprep_slave_ports() - a set bit means the channel is *not*
prepared. So after the power gate both amps sit with both channels
unprepared, indefinitely, while the manager streams data at them.

4. Why nothing complains
------------------------
tas2783-sdw declares simple_ch_prep_sm, so the core skips its entire
prepare block: it neither writes DPn_PrepareCtrl nor polls
DPn_PrepareStatus. The driver writes DPn_PrepareCtrl itself from
tas_port_prep() - as the comment there says, "TAS2783 requires explicit
port prepare during playback stream setup even when simple_ch_prep_sm is
enabled. Without this, the port fails to enter the prepared state
resulting in no audio output" - but nobody ever checks whether the port
actually reached the prepared state.

The result is a completely silent failure: the stream is enabled, the DMA
runs, the log is clean, and there is no sound.

What restores it is a full teardown: hw_free (which de-prepares the port,
writing DPn_PrepareCtrl = 0) followed by hw_params and a fresh prepare.
Re-preparing without the de-prepare - which is what a plain userspace
resume does - leaves DPn_PrepareStatus stuck. On this board I work around
it by cycling the card profile after every resume, which forces that
teardown.

Questions
---------
 - Should TAS2783 declare simple_ch_prep_sm at all? The port evidently
   does not prepare instantaneously, which is the premise of that
   property; letting the core do its normal write-and-poll would at least
   turn this into a visible error instead of silence.
 - If the property is correct, should tas_port_prep() poll
   DPn_PrepareStatus after writing DPn_PrepareCtrl, mirroring what the
   core does?
 - Either way: why does a fresh prepare not complete after the device has
   lost power, when a de-prepare followed by a prepare does? If the amp
   needs the port explicitly de-prepared before it will accept a new
   prepare after a power cycle, that sequencing has to happen somewhere
   on resume.

Happy to test patches, dump additional registers, or run traces on this
hardware.

[1] https://lore.kernel.org/all/466a905d-8203-46d2-bfe4-a3b3f9b5d68b@montane.tech/
[2] https://lore.kernel.org/all/bb5064629ada99fa5163621f72fbd27f@gmail.com/

Thanks,
Andrey

             reply	other threads:[~2026-07-27  9:33 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27  9:33 Andrey Golovko [this message]
2026-07-27 14:08 ` ASoC: tas2783-sdw: port prepare never completes after S0i3, no audio and no error (AMD ACP7.0, ASUS ProArt PX13) Pierre-Louis Bossart

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=b1bc21c8a403fe15e742b6a6ff30b27f@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=sen@ti.com \
    --cc=shenghao-ding@ti.com \
    --cc=superm1@kernel.org \
    --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.