From nobody Sun Jul 26 00:20:44 2026 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (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 C825B347535 for ; Fri, 10 Jul 2026 21:09:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783717796; cv=none; b=RiKJxW04GmjsWkU2Tx1FXOTY0QD9nsFPF+kOSKSJxJvCHbwahR98J3t5/A9Qhzvp7ON8fTyh8/7Lsy88cc6q4vaSbjtffcl6Cl4zHYcfbZNfVWBffal44BpoAphfdim+YZ1uuF9V5o6E8l+yiwhQtopKVn0p69JqRw7flkft1Ec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783717796; c=relaxed/simple; bh=KeFdEWnIy0h8OsuDM6nXoQiK/x/W2mOvEHTnodUTR0c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jMw/IFHftJwjXPtjR4dn3thWHO0a1oaCKGvDUXncA+B0lquq6bXVEhaikDD4UOLXsBrspfNy8I2jZJrZaBH9UrwZuyv4JK9Vxb8z/HupEJhvLMAJJkLUDyPDUUJeCpDD8irAqmy4fnVCfxt8FptFmhamW85Moh1+Ub+oeoaR1Gg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b=j/wW0YzD; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b="j/wW0YzD" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-4703bc0a99aso788719f8f.3 for ; Fri, 10 Jul 2026 14:09:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1783717793; x=1784322593; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=5rM5i69OmbRE0VBFYqnP7QagSMyMP9rPVK7lS65VX9Y=; b=j/wW0YzDzWIbZpJzbSttie0EX7TdlHLQ/n7xoTrkt/i10HbpbySe5n9DQr25ifLH1x QqV5sJ1r1+fyAdGvPHoS9xUHqE3jbxjDnq2fFUwovGe0parkybUI1RCrINPflvcxhjYk eoM/EEoBYSLxPM5RLI7yyNC7g6wPjm1noroa3tnyZGJeZdk8sUoEAq21waJQQv7r/6JG zuAlEKAbbiJiijNM8dbb2ZOwbxi4FHBAE9jjrl3JeOmxHwvo/POrTWAlb+30GrfiyBHJ /zJp8WdAlzpHuRWx4pT3C9wqOk2CYAJWxOliq0iVv1iXSutQQOBVBF/TMdT7d4q1hZRF 2Fdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783717793; x=1784322593; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=5rM5i69OmbRE0VBFYqnP7QagSMyMP9rPVK7lS65VX9Y=; b=BYWfMi6mKX2U8iifkFlrMiyWoz5KUVT8iGiV8RI6ao2HaKDikEKo8PNV9gJdR6F8qr NPgRao4B8lBD3WjCEnqx32HxU9WZ3MYt24uXKdB6kgAnES/3dbasXhplQciZAiw8i6aQ /WqwPfoWT4epD+xxILUtr2FtecZUMuERT4It/r3/fjfIe+zJXsP+wufBUlvN6/z6wFZJ oZJeRGjd+9Ep2n9ECaN207eoBtkPKsTTAit4I4JMobU7+JUUHqTH5a/mGdDEAeo4mHcT hAgIsBU9z8YluhdhcCC41MvAJ2ulghJvcgI3x2f9vWORiQRzF2gvppR7RmzrHkfaRbrb +PRg== X-Forwarded-Encrypted: i=1; AHgh+RqPQ6p7FWQJwDy3FcFNp1x15Sdbi1OdJIW9Nc54BFeWQY88hELBuajtKrJxKV+ypUhCeAPs9qwmHnXu2k8=@vger.kernel.org X-Gm-Message-State: AOJu0Yw43Fl5cWt++9/YnA0CuEQy4snY1jIrRLceOAAYsk1TFf+Zz6rD MnUqKnqdAGgeVIhYXb1+dkYx2Df5h8BjpZ2uA4MIqtnfsQykovMdbfjIvRW/npDb1d8= X-Gm-Gg: AfdE7cneQT2ZJWcPRQhLpgcXWjzt0RH4RHKWbhtpnKl+EYuP+4lZbIbJqwAuD0dWL3t iwvzb/Oh+lT3ezXEjd8hUDTIbrBM6EIF0756hpUGixnn5QO/9oODaSjC3iu48xKtvFTeXjVZR0u CKMYb0HGTGi/QZerXcD4flNb6NuX/8LXQSIeWuplwJzmrUSJkOX4hzc2sk2cAPM1BLYLrCsJtAm x9B6VKN2fwT6SD983ZZWU7NjNhnEwyg8S1Mc1riE7QODkhAlCrYYR2Bq+QfoD7krwcO2m4p5+YL K8THLu0dCrx3X7s3L1dPNxAnZrzNCQX0SjLqZaJMLqasa8ZPqQjRJhV6sTl2jiAfCZgc7rvKTg4 tpgBCjLJuZ0c11VOp+SZyQnFWCwDtLiveW6ZDzHHNNs2DChsPaASSsdc/RqgkBy2H24QYt97OM2 wS1cHPfWhcIw== X-Received: by 2002:a05:6000:288c:b0:473:53b7:e390 with SMTP id ffacd0b85a97d-47f2dcac225mr411001f8f.11.1783717793050; Fri, 10 Jul 2026 14:09:53 -0700 (PDT) Received: from [127.0.1.1] ([151.41.178.17]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039b0cesm64274135f8f.22.2026.07.10.14.09.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 14:09:52 -0700 (PDT) From: Valerio Setti Date: Fri, 10 Jul 2026 23:09:49 +0200 Subject: [PATCH 1/3] ASoC: meson: aiu-encoder-i2s: fix bs quirk incompatibility check Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-aiu-improve-quirk-check-v1-1-2fdd1b6f8896@baylibre.com> References: <20260710-aiu-improve-quirk-check-v1-0-2fdd1b6f8896@baylibre.com> In-Reply-To: <20260710-aiu-improve-quirk-check-v1-0-2fdd1b6f8896@baylibre.com> To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Neil Armstrong , Kevin Hilman , Martin Blumenstingl , Jerome Brunet Cc: linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org, Valerio Setti X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6429; i=vsetti@baylibre.com; h=from:subject:message-id; bh=KeFdEWnIy0h8OsuDM6nXoQiK/x/W2mOvEHTnodUTR0c=; b=owGbwMvMwCV2z3ty7kUrRgbG02pJDFmB8fN2th759Djs0mG3ipCVesvS+pLCPwg3Hr+VGf2/R KJ9lfGyjlIWBjEuBlkxRRaW6fd+F5SqPTROOFkAM4eVCWQIAxenAEzk5jmG/+ncWsvX27E90JbW upE2dYcgV+1yEcfHj+/HnGEQ/9i+8S3DPy1DZiHu+QwLVlW41GZmG7g9yu48NuGd5vKXJ9qP3/f 6wg4A X-Developer-Key: i=vsetti@baylibre.com; a=openpgp; fpr=0497DEFB707526E13360C970DE4B936DD13A0100 The bs-quirk incompatibility check has two flaws: - It only rejects one direction of the mismatch. A stream that does not require the quirk is rejected while a quirked stream is active, but the opposite is not true: a stream requiring the quirk passes the check while a non-quirked stream is active, silently reprogramming the shared mclk/bclk divider with the 50% increase and corrupting the output of the running stream. - 'bs_quirk' is only cleared in hw_free() when the last substream closes, but userspace may legally stop/reconfigure/start the stream without an intervening hw_free. Reconfiguring a single stream from the quirked configuration (8ch/16-bit) to one that does not need the quirk therefore fails with -EINVAL due to the stale flag. Drop the interface-wide flag and instead compare the quirk requirement of the incoming parameters against the committed configuration of the opposite stream at hw_params() time. The committed channels/width are cleared in hw_free() so that a released stream no longer constrains the other one. Signed-off-by: Valerio Setti --- sound/soc/meson/aiu-encoder-i2s.c | 66 +++++++++++++++++++++++++----------= ---- sound/soc/meson/gx-interface.h | 3 -- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encode= r-i2s.c index 83b579e98f1c..c2a280bfdfe2 100644 --- a/sound/soc/meson/aiu-encoder-i2s.c +++ b/sound/soc/meson/aiu-encoder-i2s.c @@ -62,13 +62,36 @@ static int aiu_encoder_i2s_set_legacy_div(struct snd_so= c_component *component, return 0; } =20 +/* + * Return true if the given combination of channels and sample width requi= res + * the bs quirk. Return false otherwise. + */ +static bool aiu_encoder_is_bs_quirk(unsigned int channels, int width) +{ + return (channels =3D=3D 8) && (width =3D=3D 16); +} + +static int aiu_encoder_check_bs_quirk(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct gx_stream *other_stream =3D snd_soc_dai_dma_data_get(dai, !substre= am->stream); + + /* Nothing to do if the other stream doesn't exist or it's not configured= yet. */ + if (!other_stream || !other_stream->channels) + return 0; + + if (aiu_encoder_is_bs_quirk(other_stream->channels, other_stream->width) = !=3D + aiu_encoder_is_bs_quirk(params_channels(params), params_width(params)= )) + return -EINVAL; + + return 0; +} + static int aiu_encoder_i2s_set_more_div(struct snd_soc_component *componen= t, struct snd_pcm_hw_params *params, unsigned int bs) { - struct aiu *aiu =3D snd_soc_component_get_drvdata(component); - struct gx_iface *iface =3D &aiu->i2s.iface; - /* * NOTE: this HW is odd. * In most configuration, the i2s divider is 'mclk / blck'. @@ -76,25 +99,13 @@ static int aiu_encoder_i2s_set_more_div(struct snd_soc_= component *component, * increased by 50% to get the correct output rate. * No idea why ! */ - if (params_width(params) =3D=3D 16 && params_channels(params) =3D=3D 8) { + if (aiu_encoder_is_bs_quirk(params_channels(params), params_width(params)= )) { if (bs % 2) { dev_err(component->dev, "Cannot increase i2s divider by 50%%\n"); return -EINVAL; } bs +=3D bs / 2; - iface->bs_quirk =3D true; - } else { - /* - * If the bs quirk is currently applied for one stream and another - * ones tries to setup a configuration for which the quirk is - * not required, then fail. - */ - if (iface->bs_quirk) { - dev_err(component->dev, - "bclk requirements are incompatible with active stream\n"); - return -EINVAL; - } } =20 /* Use CLK_MORE for mclk to bclk divider */ @@ -110,9 +121,11 @@ static int aiu_encoder_i2s_set_more_div(struct snd_soc= _component *component, return 0; } =20 -static int aiu_encoder_i2s_set_clocks(struct snd_soc_component *component, - struct snd_pcm_hw_params *params) +static int aiu_encoder_i2s_set_clocks(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { + struct snd_soc_component *component =3D dai->component; struct aiu *aiu =3D snd_soc_component_get_drvdata(component); struct gx_iface *iface =3D &aiu->i2s.iface; unsigned int srate =3D params_rate(params); @@ -133,10 +146,15 @@ static int aiu_encoder_i2s_set_clocks(struct snd_soc_= component *component, =20 bs =3D fs / 64; =20 - if (aiu->platform->has_clk_ctrl_more_i2s_div) + if (aiu->platform->has_clk_ctrl_more_i2s_div) { + if (aiu_encoder_check_bs_quirk(substream, params, dai)) { + dev_err(dai->dev, "bclk requirements incompatible with other stream\n"); + return -EINVAL; + } ret =3D aiu_encoder_i2s_set_more_div(component, params, bs); - else + } else { ret =3D aiu_encoder_i2s_set_legacy_div(component, params, bs); + } =20 if (ret) return ret; @@ -155,7 +173,6 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_sub= stream *substream, { struct gx_stream *ts =3D snd_soc_dai_get_dma_data(dai, substream); struct gx_iface *iface =3D ts->iface; - struct snd_soc_component *component =3D dai->component; int ret; =20 /* @@ -170,7 +187,7 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_sub= stream *substream, } } =20 - ret =3D aiu_encoder_i2s_set_clocks(component, params); + ret =3D aiu_encoder_i2s_set_clocks(substream, params, dai); if (ret) { dev_err(dai->dev, "setting i2s clocks failed: %d\n", ret); return ret; @@ -219,7 +236,6 @@ static int aiu_encoder_i2s_hw_free(struct snd_pcm_subst= ream *substream, if (snd_soc_dai_active(dai) <=3D 1) { aiu_encoder_i2s_divider_enable(component, 0); iface->rate =3D 0; - iface->bs_quirk =3D false; } =20 if (ts->clk_enabled) { @@ -227,6 +243,10 @@ static int aiu_encoder_i2s_hw_free(struct snd_pcm_subs= tream *substream, ts->clk_enabled =3D false; } =20 + ts->channels =3D 0; + ts->width =3D 0; + ts->physical_width =3D 0; + return 0; } =20 diff --git a/sound/soc/meson/gx-interface.h b/sound/soc/meson/gx-interface.h index 65c46dcce32a..d9ab894589fa 100644 --- a/sound/soc/meson/gx-interface.h +++ b/sound/soc/meson/gx-interface.h @@ -22,9 +22,6 @@ struct gx_iface { =20 /* For component wide symmetry */ int rate; - - /* Only for GX platform */ - int bs_quirk; }; =20 struct gx_stream { --=20 2.47.3 From nobody Sun Jul 26 00:20:44 2026 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (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 B8F91368964 for ; Fri, 10 Jul 2026 21:09:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783717798; cv=none; b=iwMy90BYxARhIc3speQMF4GYGbQNkVPfYOf8UihyLv7LCLi3R4zH4GyRGeKSseIfivjkwSufvBWkQh4zJ+YJCISW7px0ICO8IeECrQCDJ8Q4u6tSY3x+95U2fTYMMEIUNhlEhFDRDGCP8vpArIN95i3gjEbzJkeGdTRLynADTgw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783717798; c=relaxed/simple; bh=B280B5d4ZrqByaPY29NZv8op05nWwjy/iX6IvPafOwY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bQVyRgt5eEGTlegd4CQVTx7I63y14J1DsmIGA7dV/PBEMSIeMjNlrJg+FojbAB6pbS6ad//mTgveyTXDdH+kXoxEcsUMbCLpE0ih83HUccRqF3VI4zE9faxtiYX45J4wWnV4oFlIVPfISQ7YFks9iyWZm9ZuLMZUCpVquYwBrqc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b=i/5cC9wA; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b="i/5cC9wA" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-47c2b362ee2so1240153f8f.1 for ; Fri, 10 Jul 2026 14:09:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1783717794; x=1784322594; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Ps4p5IybPBy32zLyRvRZQao81FR1W1ML5zodf2gwZ7A=; b=i/5cC9wAx5thUMbcQSOSHlRuNz//l6pS/f1Mq+oVYmnj7MXVPxJpY0gNgF384LyTar D/iFdo1PcbBRiet8QJ3Ysmw1WycyYiKFcLz9h5A1gpPR+uI7cyMuhlGG2BKB5N4vSo+o iSWWgD37iH1bl7/nrEQsGTvfbWlOEkZ0O/mRgiCcRUkyvO5/zU+O+yIC/mKflOwgohFY 7a+tHQfFnMMqMGSOKOizCaOT8N/dQ/+tZ+YSSQzbuEtYYNoSWyM1LYKXT9ao4zVg3vHP zzzmde6WrnzHh0t2ogcwqiaeqYpybyTSIoUS4ml9TIoYBoXK8LmJ65Eijkw+GEKLt/kU +Q/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783717794; x=1784322594; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Ps4p5IybPBy32zLyRvRZQao81FR1W1ML5zodf2gwZ7A=; b=Le3T+trv732FKSVg1/B7qmELg61tSFmcnvZiDVvz3LDCR2+9cuuHNbBVlUv+Mb72j2 ZC+ci8IsVyklTTSvop004Y8Ft4ZL1G5EwcRVgoFV3hQ4cFMSlfyhYxBEN2T7wHzb5o4D FThmLhiyeVsqJ3frTe3oh7WKOpIBMffATDReviT71S9oJHHHz8kUiYP99Vts+u+sAQwy rfnxRiBrgp6bsi6fAB5yf1t4fquyX+aQRT5PnbZJdsZlczE/scfuvgQEoQ2gSJpnenrJ 5BSVKPWI8IXxSlUK4C+edFjL0OEpRv8haLzQZX4OIed9eVxLhiC9bBrhg+2fgymcimST KLbA== X-Forwarded-Encrypted: i=1; AHgh+RoRD/nVWMoutI93kKMLIeZQ/od8g3fFxNxWbQ1uR5fpL5H/42INvwF0spMUqP6VHu8u2qgR3tRPSJLqfKY=@vger.kernel.org X-Gm-Message-State: AOJu0YwIhV64OL8u1a3k6/4ldpJwSLAZjf8JNOqHoevFELugu8LBdUo1 E0/vzoZlSAJKior8v/nNP6KJ9P6G7VcFUzxvqqRtOXcYtX6KOzYBb6cqgrvLzFCk1dM= X-Gm-Gg: AfdE7clxK+0lv6fGQzi7REqYIxeP8zrjvr9SSkNweD0V7djVbPPhCjJRqT0InPLWBAe 8NPPzZpLWQPHToDMQ0Mmm9AfqUYhKUiAPc/PbV9i45FkqmuOQdXro8A/QmQPEhOJJQpATskUmUz RU2KHgUoTc2Box2kjjoy5b8k9h1qmEXnGg6WNUnMT09Dp1swpK2Bd9jCmkzOPr5pHF4WMTZ5/sD Qzyed+c+/vuv0nrcLJdPJnHOQYFh3hcn0LsAUTTcotu5R+/jRzkGIGmVrA4/N51CcrUOTcrAOIr XVtSDnQ4PlL+LgS8+eerLwPel2eby0RVoS6KNOE2XhJ9fiq2VLRtJSqkboV/Dhm/rU+YkzicrVe NJhdxAZhN8z9qPUUyJF32O9DIlR4KW8I5k/fXcdPpGQkjcU+z7KG/Hx3TJzuCWcuwnc30yOWMKR daqnpL5D4VaQ== X-Received: by 2002:a05:6000:481a:b0:472:fe1a:1ee9 with SMTP id ffacd0b85a97d-47f2dcb5afbmr430808f8f.20.1783717794169; Fri, 10 Jul 2026 14:09:54 -0700 (PDT) Received: from [127.0.1.1] ([151.41.178.17]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039b0cesm64274135f8f.22.2026.07.10.14.09.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 14:09:53 -0700 (PDT) From: Valerio Setti Date: Fri, 10 Jul 2026 23:09:50 +0200 Subject: [PATCH 2/3] ASoC: meson: aiu-encoder-i2s: reflect bs quirk in hw constraints Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-aiu-improve-quirk-check-v1-2-2fdd1b6f8896@baylibre.com> References: <20260710-aiu-improve-quirk-check-v1-0-2fdd1b6f8896@baylibre.com> In-Reply-To: <20260710-aiu-improve-quirk-check-v1-0-2fdd1b6f8896@baylibre.com> To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Neil Armstrong , Kevin Hilman , Martin Blumenstingl , Jerome Brunet Cc: linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org, Valerio Setti X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5327; i=vsetti@baylibre.com; h=from:subject:message-id; bh=B280B5d4ZrqByaPY29NZv8op05nWwjy/iX6IvPafOwY=; b=owGbwMvMwCV2z3ty7kUrRgbG02pJDFmB8fN4TkYKKXVy+ubGSOYxhHa33lzAKb/gseizPwry3 jOvl7N0lLIwiHExyIopsrBMv/e7oFTtoXHCyQKYOaxMIEMYuDgFYCJrrBn+Z1ovncn1efe6hf95 qpfqMc1mUPzZw2z38+TfXdNeL1b7b8/IcLu05LjCYXexkykJP6LtGvh+rdR9tP1Yy4zVLGVOEQ/ V2AA= X-Developer-Key: i=vsetti@baylibre.com; a=openpgp; fpr=0497DEFB707526E13360C970DE4B936DD13A0100 Currently the only check for bs-quirk is implemented in hw_params(), but this is too late: nothing in the refined hw parameters hints at the restriction, so userspace has no way to know the configuration is invalid until the setup fails, as Jerome pointed out during review [1]. Add hw rules on CHANNELS and SAMPLE_BITS at startup() so that the restriction shows up during parameter refinement instead. The rules are refined against the committed configuration of the opposite stream: - if it uses the quirk, the current stream is narrowed to the same 8ch/16-bit configuration; - otherwise, selecting a 16-bit physical width limits the stream to 2 channels, and selecting 8 channels requires a physical width larger than 16 bits. The rules key on the physical width while the quirk is defined on the significant bits. This is safe because S16_LE is the only format supported by the encoder where both are 16 bits. The check in aiu_encoder_i2s_set_clocks() is kept as the last backstop: both streams may be refined concurrently before either commits its configuration. The rules are only registered on GX platforms where the bs-quirk exists and only when the DAI has a stream in the opposite direction. [1] https://lore.kernel.org/r/1jik7pebk7.fsf@starbuckisacylon.baylibre.com/ Suggested-by: Jerome Brunet Signed-off-by: Valerio Setti --- sound/soc/meson/aiu-encoder-i2s.c | 67 +++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 67 insertions(+) diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encode= r-i2s.c index c2a280bfdfe2..4c62ea41d7e8 100644 --- a/sound/soc/meson/aiu-encoder-i2s.c +++ b/sound/soc/meson/aiu-encoder-i2s.c @@ -147,6 +147,13 @@ static int aiu_encoder_i2s_set_clocks(struct snd_pcm_s= ubstream *substream, bs =3D fs / 64; =20 if (aiu->platform->has_clk_ctrl_more_i2s_div) { + /* + * The hw rules added in startup() make this unreachable in the + * sequential case, but both streams may be refined concurrently + * before either commits its config, since only ops->hw_params + * runs under the card's pcm_mutex. Re-check against the committed + * state of the other stream, which is stable under that mutex. + */ if (aiu_encoder_check_bs_quirk(substream, params, dai)) { dev_err(dai->dev, "bclk requirements incompatible with other stream\n"); return -EINVAL; @@ -333,10 +340,45 @@ static const struct snd_pcm_hw_constraint_list hw_cha= nnel_constraints =3D { .mask =3D 0, }; =20 +static int aiu_encoder_i2s_pcm_hw_rule(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct gx_stream *other =3D rule->private; + struct snd_interval *ch =3D hw_param_interval(params, SNDRV_PCM_HW_PARAM_= CHANNELS); + /* + * The quirk is technically based on the significant bits whereas here + * we're using the physical width for simplicity. This works because + * S16_LE is the only format supported by this encoder that has: + * significant bits =3D physical width =3D 16-bits + */ + struct snd_interval *phys_width =3D hw_param_interval(params, SNDRV_PCM_H= W_PARAM_SAMPLE_BITS); + struct snd_interval new_i; + + if (other->channels =3D=3D 0) + return 0; + + snd_interval_any(&new_i); + + if (rule->var =3D=3D SNDRV_PCM_HW_PARAM_CHANNELS) { + if (aiu_encoder_is_bs_quirk(other->channels, other->width)) + new_i.min =3D new_i.max =3D 8; + else if (snd_interval_single(phys_width) && phys_width->min =3D=3D 16) + new_i.max =3D 2; /* Force 2ch */ + } else { /* SNDRV_PCM_HW_PARAM_SAMPLE_BITS */ + if (aiu_encoder_is_bs_quirk(other->channels, other->width)) + new_i.min =3D new_i.max =3D 16; + else if (snd_interval_single(ch) && ch->min =3D=3D 8) + new_i.min =3D 17; /* Request physical width > 16 bits */ + } + + return snd_interval_refine(hw_param_interval(params, rule->var), &new_i); +} + static int aiu_encoder_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct aiu *aiu =3D snd_soc_component_get_drvdata(dai->component); + struct gx_stream *other_stream =3D snd_soc_dai_dma_data_get(dai, !substre= am->stream); int ret; =20 /* Make sure the encoder gets either 2 or 8 channels */ @@ -348,6 +390,31 @@ static int aiu_encoder_i2s_startup(struct snd_pcm_subs= tream *substream, return ret; } =20 + /* + * If DAI supports both playback and capture streams ensure the bs-quirk = is + * handled correctly. + * This is only valid for GX platforms (has_clk_ctrl_more_i2s_div=3Dtrue). + */ + if (aiu->platform->has_clk_ctrl_more_i2s_div && other_stream) { + ret =3D snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + aiu_encoder_i2s_pcm_hw_rule, + other_stream, + SNDRV_PCM_HW_PARAM_CHANNELS, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); + if (ret) + return ret; + + ret =3D snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + aiu_encoder_i2s_pcm_hw_rule, + other_stream, + SNDRV_PCM_HW_PARAM_CHANNELS, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); + if (ret) + return ret; + } + /* * Enable only clocks which are required for the interface internal * logic. MCLK is enabled/disabled from the formatter and the I2S --=20 2.47.3 From nobody Sun Jul 26 00:20:44 2026 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (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 C40F73B2FE6 for ; Fri, 10 Jul 2026 21:09:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783717798; cv=none; b=qWZ+zcfeBnkr9F11Pb2zFuBGdAoW7YNqwlBTEOYT2GX1b8yWSz1yjmoYAbYJsoSVFZvAJxVQ0tlR7PMc2Iw4P4lBsTYhkl/iFokNZiyRVDGx+iQnuJi0ctDjDu9tz+/zmvs5uPmV9tIvCWJ99RweiJt+v66we7aSV9aPALwspy0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783717798; c=relaxed/simple; bh=KLOO+A+1/5XLck9wFIUskRNAYu38bZZV9QraigMfjJc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LaPPHRk0XSzK1Hee5Cdsxc/iAjtiz+QYrQ+qj9RrdwolAn6I5APS6f+fr5ux31crPh/LTUP1BMul/XpGq9yviBIu0jfPYF5iimNznVU/OXYhjk5cKnv4RVuo2jYM9ExQCR/5/uqkU9e0rZ6FKSuNnYQ8GCCqFcsBN4dB+1Em6Ds= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b=EDVQs9CJ; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b="EDVQs9CJ" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-4759b4f0897so794286f8f.1 for ; Fri, 10 Jul 2026 14:09:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1783717795; x=1784322595; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=nJ4cp+Dez60Lk/0/twpxfAxM2T1ZemRxFXgI3U5E6xA=; b=EDVQs9CJl5S5T70WVvBOkAxOlh8gR8dX4JraJXazpLob09KEpHSB/I+aEGUnYD5alw +QjNpSEbmmxSzbjvVIEPuTv8b6WwFHXCGAuvCwFdpVavF7/IhxtGjgzkQZjkp0eKvk34 FO4yGnVxoqaEFRk7ofqujNCr9yzQYD8x8/FnBKHryXvUjtBNB8Sa0vw0KzalZVnpAv5p XW7D0DxZUqqK+bavwt9tun3a6fMLtq16i27zXmCflmAIEDHj3T99r8Jve0pjsNvIEmAU Sozqs2avfXXxSfwXam5BC3vPT+0LfYydPKjHZf7ch+dnF0+58yvwYSD+3mwQOkiSZYpL YnlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783717795; x=1784322595; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=nJ4cp+Dez60Lk/0/twpxfAxM2T1ZemRxFXgI3U5E6xA=; b=hgosgMw5iAB3MPGtYNOLk21acqwAjfN0kDCO5ZbU0Aw3ScUpfOuj8ZBcOcGyQYeNEE g6UdLG/nbwqMMCCrVJaQRY5Lx3NogjRwl0KGbcAnsyCbEtsfdDZZz9khng+QxZxZZfaG kjMczmnvu29FJD+GEDPfOMizRi9ARuuxBcH4Adse66WcYE58DqBkcv81dSoTxohAbnHS 0qmr/MctEN784nsBpDgfNgC4B1Scs5D2CPCpdvy44+URPvF+nd815vSRX+ELX9TRIXrK LWPgfuFJ2vlXpfocFRAG8xrQToCbkmP02kfANg0ML/nMJxBYDyKJVcYH6x2ncCLuhImG wmeA== X-Forwarded-Encrypted: i=1; AHgh+RrsY+4CArSGgDuP7UohaZg+7Sggb9URSLu08qNbpa2tJRpthW0DaNTWw1y3K28hSy6bTGAWTXH75gIdg0Q=@vger.kernel.org X-Gm-Message-State: AOJu0YwcEUbJNNHi5I08JtQtU17vPs01ckZxY4U0BufKvYNYXUYpJRl1 g1FQmdb1vkNerfZUPcaPgNx0E5r/3FsaCirxdQ3kmd6NR4Z2IXNBeOZoG8xWISa81UY= X-Gm-Gg: AfdE7cn2yhGA6luwXyKHacZxYiYeomtlMCYymhCZzBIes3HR+iOOjuI8qQGfs1i5YUu Q2P0HXbvGJgDeaxd1AzJNMArmeNm+qiw9S2V+VJPOchzYxnqTPoVIrCaYBar1ifGPOdBmR1j49e /sQNyto8DO+fG12BjYrWFpz+PgP1Os3YJcdma11tk6Ke/UJxNAe+Saq1T8s+ETc5EQbSC2x0Nk7 vWKr1N8Ayun1/Xaew4gQo8JGl16eF7+UCH/FvWGX5v2tPxYluGA9pTiXPG0Ve7J+0y6lwcUfG0c Lud/fn2/U1ohJcxtYr6xkUskELH2dVoFdXVkzgeMs5yb7HLRhJxGVyPOKqaX7Y/PT4uFgvrx6rG 5IBUxaRWe5nybT0VBrTH+XTR7lymVY5PY0yUVte2YEU8KAJeB1oCBLfykGVF2VQ7AJKJhGen1Wh h8AcT7bnYY1A== X-Received: by 2002:a05:6000:25fe:b0:475:5e4b:588e with SMTP id ffacd0b85a97d-47f2dc9bf45mr393022f8f.20.1783717795139; Fri, 10 Jul 2026 14:09:55 -0700 (PDT) Received: from [127.0.1.1] ([151.41.178.17]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039b0cesm64274135f8f.22.2026.07.10.14.09.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 14:09:54 -0700 (PDT) From: Valerio Setti Date: Fri, 10 Jul 2026 23:09:51 +0200 Subject: [PATCH 3/3] ASoC: meson: aiu-encoder-i2s: use the core symmetric_rate handling Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-aiu-improve-quirk-check-v1-3-2fdd1b6f8896@baylibre.com> References: <20260710-aiu-improve-quirk-check-v1-0-2fdd1b6f8896@baylibre.com> In-Reply-To: <20260710-aiu-improve-quirk-check-v1-0-2fdd1b6f8896@baylibre.com> To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Neil Armstrong , Kevin Hilman , Martin Blumenstingl , Jerome Brunet Cc: linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org, Valerio Setti X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3679; i=vsetti@baylibre.com; h=from:subject:message-id; bh=KLOO+A+1/5XLck9wFIUskRNAYu38bZZV9QraigMfjJc=; b=owGbwMvMwCV2z3ty7kUrRgbG02pJDFmB8fMqPrE8nRhfP30LO/vfSM6k6H9Wd/a1p3H6RzIu9 vv7+MuEjlIWBjEuBlkxRRaW6fd+F5SqPTROOFkAM4eVCWQIAxenAEyEX4fhn2KGWnPtrGvbgg+5 /879806yOteupubvqj8RZ5dPXFH0bA0jw0MB3nTWTR/lv4i80mewK3trLxL4/eBbtb2HtG397W6 +5QQA X-Developer-Key: i=vsetti@baylibre.com; a=openpgp; fpr=0497DEFB707526E13360C970DE4B936DD13A0100 The driver manually implement the interface-wide rate symmetry enforcement in hw_params(), which suffers from the same problem addressed in the previous patch: the restriction is not visible in the hw parameter constraints, so a stream with a mismatching rate only finds out via -EINVAL late in the stream setup. The ASoC core already provides this feature through the DAI's 'symmetric_rate' flag: when another stream of the DAI is active, soc_pcm_apply_symmetry() constrains the rate at open time so the restriction shows up during parameter refinement, and soc_pcm_params_symmetry() still rejects a mismatch at hw_params() time as a backstop. Set 'symmetric_rate' on the I2S encoder DAI and drop the open-coded check along with the now unused 'rate' member of struct gx_iface. Signed-off-by: Valerio Setti --- sound/soc/meson/aiu-encoder-i2s.c | 21 ++------------------- sound/soc/meson/aiu.c | 1 + sound/soc/meson/gx-interface.h | 3 --- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encode= r-i2s.c index 4c62ea41d7e8..58dce9f08c9d 100644 --- a/sound/soc/meson/aiu-encoder-i2s.c +++ b/sound/soc/meson/aiu-encoder-i2s.c @@ -179,28 +179,14 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_s= ubstream *substream, struct snd_soc_dai *dai) { struct gx_stream *ts =3D snd_soc_dai_get_dma_data(dai, substream); - struct gx_iface *iface =3D ts->iface; int ret; =20 - /* - * Enforce interface wide rate symmetry only if there is more than - * 1 stream active. - */ - if (snd_soc_dai_active(dai) > 1) { - if (iface->rate && iface->rate !=3D params_rate(params)) { - dev_err(dai->dev, "can't set iface rate (%d !=3D %d)\n", - iface->rate, params_rate(params)); - return -EINVAL; - } - } - ret =3D aiu_encoder_i2s_set_clocks(substream, params, dai); if (ret) { dev_err(dai->dev, "setting i2s clocks failed: %d\n", ret); return ret; } =20 - iface->rate =3D params_rate(params); ts->physical_width =3D params_physical_width(params); ts->width =3D params_width(params); ts->channels =3D params_channels(params); @@ -233,17 +219,14 @@ static int aiu_encoder_i2s_hw_free(struct snd_pcm_sub= stream *substream, struct snd_soc_dai *dai) { struct gx_stream *ts =3D snd_soc_dai_get_dma_data(dai, substream); - struct gx_iface *iface =3D ts->iface; struct snd_soc_component *component =3D dai->component; =20 /* * If this is the last substream being closed then disable the i2s - * clock divider and clear 'iface->rate'. + * clock divider. */ - if (snd_soc_dai_active(dai) <=3D 1) { + if (snd_soc_dai_active(dai) <=3D 1) aiu_encoder_i2s_divider_enable(component, 0); - iface->rate =3D 0; - } =20 if (ts->clk_enabled) { clk_disable_unprepare(ts->iface->mclk); diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c index 64ace4d25d92..2668646e3597 100644 --- a/sound/soc/meson/aiu.c +++ b/sound/soc/meson/aiu.c @@ -154,6 +154,7 @@ static struct snd_soc_dai_driver aiu_cpu_dai_drv[] =3D { .formats =3D AIU_FORMATS, }, .ops =3D &aiu_encoder_i2s_dai_ops, + .symmetric_rate =3D 1, }, [CPU_SPDIF_ENCODER] =3D { .name =3D "SPDIF Encoder", diff --git a/sound/soc/meson/gx-interface.h b/sound/soc/meson/gx-interface.h index d9ab894589fa..2a6207e393e8 100644 --- a/sound/soc/meson/gx-interface.h +++ b/sound/soc/meson/gx-interface.h @@ -19,9 +19,6 @@ struct gx_iface { =20 /* format is common to all the DAIs of the iface */ unsigned int fmt; - - /* For component wide symmetry */ - int rate; }; =20 struct gx_stream { --=20 2.47.3