On Thu, Jun 26, 2025 at 9:09 PM Arun Raghavan <a...@arunraghavan.net> wrote: > > From: Arun Raghavan <a...@asymptotic.io> > > On an imx8mm platform with an external clock provider, when running the > receiver (arecord) and triggering an xrun with xrun_injection, we see a > channel swap/offset. This happens sometimes when running only the > receiver, but occurs reliably if a transmitter (aplay) is also > concurrently running. > > It seems that the SAI loses track of frame sync during the trigger stop > -> trigger start cycle that occurs during an xrun. Doing just a FIFO > reset in this case does not suffice, and only a software reset seems to > get it back on track. > > This looks like the same h/w bug that is already handled for the > producer case, so we now do the reset unconditionally on config disable. > > Signed-off-by: Arun Raghavan <a...@asymptotic.io> > Reported-by: Pieterjan Camerlynck <p.camerly...@televic.com> > Fixes: 3e3f8bd56955 ("ASoC: fsl_sai: fix no frame clk in master mode") > Cc: sta...@vger.kernel.org
Acked-by: Shengjiu Wang <shengjiu.w...@gmail.com> Best regards Shengjiu Wang > --- > > v4 > - Add Fixes and cc stable > > v3 > - Incorporate feedback from Shengjiu Wang to consolidate with the > existing handling of this issue in producer mode > > v2 (no longer relevant) > - Address build warning from kernel test robot > > sound/soc/fsl/fsl_sai.c | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > > diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c > index af1a168d35e3..50af6b725670 100644 > --- a/sound/soc/fsl/fsl_sai.c > +++ b/sound/soc/fsl/fsl_sai.c > @@ -803,13 +803,15 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, > int dir) > * anymore. Add software reset to fix this issue. > * This is a hardware bug, and will be fix in the > * next sai version. > + * > + * In consumer mode, this can happen even after a > + * single open/close, especially if both tx and rx > + * are running concurrently. > */ > - if (!sai->is_consumer_mode[tx]) { > - /* Software Reset */ > - regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), > FSL_SAI_CSR_SR); > - /* Clear SR bit to finish the reset */ > - regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0); > - } > + /* Software Reset */ > + regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR); > + /* Clear SR bit to finish the reset */ > + regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0); > } > > static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, > -- > 2.49.0 >