From nobody Tue Sep 29 04:11:10 2026 Received: from mail-lf1-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8653148B383 for ; Wed, 12 Aug 2026 21:29:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786570168; cv=none; b=gRIcTR+ZTrvqvMlW4bXw+ddiE+aSYolg0/VxEwRLUvBaNaDijyettWv/PXWzwr8e+5U/eN4xgpijVaiCmVXXof20BH9HEsLvfJ7ELhn2UcKqkogvMvgxr4tqV9H6s+RnZxayaAiyIWF0I/osBVD1aBq9nV7f4EOcOCQYblHE7Yo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786570168; c=relaxed/simple; bh=6o9u6odSECXn/Sqpo3ZEcFEnm6JKjYPT6jApYic+w8A=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=TSkjzwFgQhHAn0FBjqZq4v+sPVDOlQ8NNSDHJukR6CK3YgQTrxbTVzoFs+j753LWZ4YNbUfOP4hXAWZrnQBu1F4iAIh+KCnP3yYc7oRCdVIJm3IPGPEhlxFBqnkt3WK9k7Px/5VV0RwsiEKDKM6NtLP0mB9VeH5n7vX41DsHH40= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=H4BskAfB; arc=none smtp.client-ip=209.85.167.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="H4BskAfB" Received: by mail-lf1-f51.google.com with SMTP id 2adb3069b0e04-5b29599b81cso65396e87.1 for ; Wed, 12 Aug 2026 14:29:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786570164; x=1787174964; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:message-id:date :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to :content-type; bh=APNfoquVENaFKAsc+zGS7Ne6Uj+23RMfT8VAp0rzc7k=; b=H4BskAfBDaI2SQhKSF45k/3fMpWJmEgdSGoUOU2LJKAe2Z4Td+XFSAKytDeFxBBwCj 7VA0ButLHxQfE5DohR1rILzHhDps6LIly/faftQrlPAemHdXsTQ2/BEs5IqKlzUucdpz VSC6VQbkVCnG+FhflYkJLHYbsDxhjPI9p+C68Xm4/DWiP+rUo3BVVZVyGaV5Ds6tr7GX qAoMm+Swh1N3AE9nWnpuSrvx0tbYVWG8tNNApl3uwtUdEbpVGimvenAJfTdo0wpsa+mj iHkyaxnvFkNzMK2qnccFiKC7HYKYpe/IG3YMxexd26BC7G0pjGarMRULS4piki1uDyHM rR8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786570164; x=1787174964; h=content-transfer-encoding:content-type:mime-version:message-id:date :subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to:content-type; bh=APNfoquVENaFKAsc+zGS7Ne6Uj+23RMfT8VAp0rzc7k=; b=jDxO9CjiqgsIEBSHpH139WRGnRdX1oD3LYyBibLFlR0cQLymPN7xtTA2Bs5SffL5p4 gKYScbXi34XWq6AQCa1dPZhToJenERucB9k8NLSPcppSVtPZ5MKZ34VzAZq2Gsae51HD RNpWB2dIoKTEYGWqzNzSAKw+fNDFQZzH9dG+Z0Lm/JKe86G9zN4TkMgnBFhwJ4z+8Y4D 4qiNN6qH8VRWAGngcaOdm5Wq3tBjdT8apWdNb1plcnoVVSfMAMHV35Yj57ugkwHwwIx1 HKuIuGFQgdA9W00Ev3pDRGlodiBcf814AnUMqwdi2rdIMmVNlLndoS1GaSZjbXG/47NP d1fg== X-Forwarded-Encrypted: i=1; AHgh+Rr4IKFks3zMJWrp4xGpALVV/SzK3f9pXdbSj+Wy+4B7qMZdgMTvgyklTW/OEw37fxW0dNR/yZSJruglLGg=@vger.kernel.org X-Gm-Message-State: AOJu0YyAB1FAG7isTTV9egtw9OL/zSz1xAiQ+ebwcALEoGa3IM7DxSK7 P0DUH1hJiFi1qiXIztsAfJ0FZy1itn19O5Vjy93DtE6UfmcCjBuzskb9oKndkgTf+rmEbQ== X-Gm-Gg: AR+sD13cNrOmZbH+fcfdSYaBbkqxMm7Ds8TtJxRc6X9mxkQ9k6Hf/NJLb7XTutff+yp LDGzR4plCcXdbWWKGu3PPmIFJRI1rqmz33V6fkk5TMolKslO1EXzuZP7GJ1KMOViz/Gm4vozgCv ayf6jIaOzLEaU4SofbSwNjdjyMTCIDeP7iRbZudAEhOtDdSBQxIEPehMNosN/V65M56bgvnFqHB kAxG1I9cH1fDzFfNkZLi29XCVFnaemKVbuTVxn1I6evKTMOgn7k1RR8q+nl6M5O0BIb7GUHPB4o TfNumBUVyrT95Vz1KcZy4cKz36K33ZsArij9ScCzpphBBCugrA+odXwdKu9aHcdHyb02bHzvxpt I6WQUDxLLhsSCZ0smNScWtTB1idsRilhrZ6wukvOTx6l8kSQzCcnM2QVmz42wWT7/aa+YStukwP tN5UH5RciMpoX5ehjV3SITYmhH5mbRbAYOYrkTXD6VXCPfx1Q/ueaVlgdaLRQyDHyfn07U1qZcw VXk3UIaLyTOAS8gtxWJdTvSFXnKmFTLTQ== X-Received: by 2002:a05:6512:a457:b0:5ae:c926:fc18 with SMTP id 2adb3069b0e04-5b453f85043mr51373e87.38.1786570164213; Wed, 12 Aug 2026 14:29:24 -0700 (PDT) Received: from localhost (host-80-73-162-2.rev.as20985.net. [80.73.162.2]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b453a66a74sm67893e87.71.2026.08.12.14.29.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Aug 2026 14:29:23 -0700 (PDT) From: Andrey Golovko To: Shenghao Ding , Kevin Lu , Baojun Xu , Sen Wang , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: "Holalu Yogendra, Niranjan" , Pierre-Louis Bossart , Vijendar Mukunda , Antoine Monnet , Robin Everaars , Ville Saarinen , 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 Message-ID: <20260813001500.9218-1-andrey.golovko@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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=3D0x3 act=3D0x3 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=3D0x0 act=3D0x0 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.co= m/ 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, str= uct sdw_prepare_ch *prep_ch enum sdw_port_prep_ops pre_ops) { struct device *dev =3D &slave->dev; + struct tas2783_prv *tas_dev =3D 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, st= ruct sdw_prepare_ch *prep_ch addr =3D 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 =3D 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=3D%d\n", + prep_ch->num, ret); + return ret; + } + ret =3D sdw_write_no_pm(slave, addr, prep_ch->ch_mask); if (ret) dev_err(dev, "prep failed for port %d, err=3D%d\n", base-commit: 6f6fb37f9f9a8ae88faa1b5b1978e57381488502 --=20 2.53.0