2024-04-26 15:55:03

by Jerome Brunet

[permalink] [raw]
Subject: [PATCH 0/4] ASoC: meson: tdm fixes

This patchset fixes 2 problems on TDM which both find a solution
by properly implementing the .trigger() callback for the TDM backend.

ATM, enabling the TDM formatters is done by the .prepare() callback
because handling the formatter is slow due to necessary calls to CCF.

The first problem affects the TDMIN. Because .prepare() is called on DPCM
backend first, the formatter are started before the FIFOs and this may
cause a random channel shifts if the TDMIN use multiple lanes with more
than 2 slots per lanes. Using trigger() allows to set the FE/BE order,
solving the problem.

There has already been an attempt to fix this 3y ago [1] and reverted [2]
It triggered a 'sleep in irq' error on the period IRQ. The solution is
to just use the bottom half of threaded IRQ. This is patch #1. Patch #2
and #3 remain mostly the same as 3y ago.

For TDMOUT, the problem is on pause. ATM pause only stops the FIFO and
the TDMOUT just starves. When it does, it will actually repeat the last
sample continuously. Depending on the platform, if there is no high-pass
filter on the analog path, this may translate to a constant position of
the speaker membrane. There is no audible glitch but it may damage the
speaker coil.

Properly stopping the TDMOUT in pause solves the problem. There is
behaviour change associated with that fix. Clocks used to be continuous
on pause because of the problem above. They will now be gated on pause by
default, as they should. The last change introduce the proper support for
continuous clocks, if needed.

[1]: https://lore.kernel.org/linux-amlogic/[email protected]
[2]: https://lore.kernel.org/linux-amlogic/[email protected]

Jerome Brunet (4):
ASoC: meson: axg-fifo: use threaded irq to check periods
ASoC: meson: axg-card: make links nonatomic
ASoC: meson: axg-tdm-interface: manage formatters in trigger
ASoC: meson: axg-tdm: add continuous clock support

sound/soc/meson/axg-card.c | 1 +
sound/soc/meson/axg-fifo.c | 29 +++++++++++++--------
sound/soc/meson/axg-tdm-formatter.c | 40 +++++++++++++++++++++++++++++
sound/soc/meson/axg-tdm-interface.c | 38 +++++++++++++++++++--------
sound/soc/meson/axg-tdm.h | 5 ++++
5 files changed, 93 insertions(+), 20 deletions(-)

--
2.43.0



2024-04-26 15:55:13

by Jerome Brunet

[permalink] [raw]
Subject: [PATCH 1/4] ASoC: meson: axg-fifo: use threaded irq to check periods

With the AXG audio subsystem, there is a possible random channel shift on
TDM capture, when the slot number per lane is more than 2, and there is
more than one lane used.

The problem has been there since the introduction of the axg audio support
but such scenario is pretty uncommon. This is why there is no loud
complains about the problem.

Solving the problem require to make the links non-atomic and use the
trigger() callback to start FEs and BEs in the appropriate order.

This was tried in the past and reverted because it caused the block irq to
sleep while atomic. However, instead of reverting, the solution is to call
snd_pcm_period_elapsed() in a non atomic context.

Use the bottom half of a threaded IRQ to do so.

Fixes: 6dc4fa179fb8 ("ASoC: meson: add axg fifo base driver")
Signed-off-by: Jerome Brunet <[email protected]>
---
sound/soc/meson/axg-fifo.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c
index bebee0ca8e38..ecb3eb7a9723 100644
--- a/sound/soc/meson/axg-fifo.c
+++ b/sound/soc/meson/axg-fifo.c
@@ -204,18 +204,26 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id)
unsigned int status;

regmap_read(fifo->map, FIFO_STATUS1, &status);
-
status = FIELD_GET(STATUS1_INT_STS, status);
+ axg_fifo_ack_irq(fifo, status);
+
+ /* Use the thread to call period elapsed on nonatomic links */
if (status & FIFO_INT_COUNT_REPEAT)
- snd_pcm_period_elapsed(ss);
- else
- dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n",
- status);
+ return IRQ_WAKE_THREAD;

- /* Ack irqs */
- axg_fifo_ack_irq(fifo, status);
+ dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n",
+ status);
+
+ return IRQ_NONE;
+}
+
+static irqreturn_t axg_fifo_pcm_irq_block_thread(int irq, void *dev_id)
+{
+ struct snd_pcm_substream *ss = dev_id;
+
+ snd_pcm_period_elapsed(ss);

- return IRQ_RETVAL(status);
+ return IRQ_HANDLED;
}

int axg_fifo_pcm_open(struct snd_soc_component *component,
@@ -243,8 +251,9 @@ int axg_fifo_pcm_open(struct snd_soc_component *component,
if (ret)
return ret;

- ret = request_irq(fifo->irq, axg_fifo_pcm_irq_block, 0,
- dev_name(dev), ss);
+ ret = request_threaded_irq(fifo->irq, axg_fifo_pcm_irq_block,
+ axg_fifo_pcm_irq_block_thread,
+ IRQF_ONESHOT, dev_name(dev), ss);
if (ret)
return ret;

--
2.43.0


2024-05-01 13:43:51

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 0/4] ASoC: meson: tdm fixes

On Fri, 26 Apr 2024 17:29:37 +0200, Jerome Brunet wrote:
> This patchset fixes 2 problems on TDM which both find a solution
> by properly implementing the .trigger() callback for the TDM backend.
>
> ATM, enabling the TDM formatters is done by the .prepare() callback
> because handling the formatter is slow due to necessary calls to CCF.
>
> The first problem affects the TDMIN. Because .prepare() is called on DPCM
> backend first, the formatter are started before the FIFOs and this may
> cause a random channel shifts if the TDMIN use multiple lanes with more
> than 2 slots per lanes. Using trigger() allows to set the FE/BE order,
> solving the problem.
>
> [...]

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/4] ASoC: meson: axg-fifo: use threaded irq to check periods
commit: b11d26660dff8d7430892008616452dc8e5fb0f3
[2/4] ASoC: meson: axg-card: make links nonatomic
commit: dcba52ace7d4c12e2c8c273eff55ea03a84c8baf
[3/4] ASoC: meson: axg-tdm-interface: manage formatters in trigger
commit: f949ed458ad15a00d41b37c745ebadaef171aaae
[4/4] ASoC: meson: axg-tdm: add continuous clock support
commit: a5a89037d080e0870d7517c61f8b2123d58ab33b

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark