[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250916123118.84175-1-olivier.moysan@foss.st.com>
Date: Tue, 16 Sep 2025 14:31:18 +0200
From: Olivier Moysan <olivier.moysan@...s.st.com>
To: <kuninori.morimoto.gx@...esas.com>,
Olivier Moysan
<olivier.moysan@...s.st.com>,
Arnaud Pouliquen
<arnaud.pouliquen@...s.st.com>,
Liam Girdwood <lgirdwood@...il.com>,
"Mark
Brown" <broonie@...nel.org>, Jaroslav Kysela <perex@...ex.cz>,
Takashi Iwai
<tiwai@...e.com>,
Maxime Coquelin <mcoquelin.stm32@...il.com>,
"Alexandre
Torgue" <alexandre.torgue@...s.st.com>
CC: <linux-sound@...r.kernel.org>, <linux-stm32@...md-mailman.stormreply.com>,
<linux-arm-kernel@...ts.infradead.org>, <linux-kernel@...r.kernel.org>
Subject: [PATCH] ASoC: stm32: sai: manage context in set_sysclk callback
The mclk direction now needs to be specified in endpoint node with
"system-clock-direction-out" property. However some calls to the
set_sysclk callback, related to CPU DAI clock, result in unbalanced
calls to clock API.
The set_sysclk callback in STM32 SAI driver is intended only for mclk
management. So it is relevant to ensure that calls to set_sysclk are
related to mclk only.
Since the master clock is handled only at runtime, skip the calls to
set_sysclk in the initialization phase.
Signed-off-by: Olivier Moysan <olivier.moysan@...s.st.com>
---
Here is feedback regarding commit 5725bce709db1c001140d79398581e067e28c031
ASoC: simple-card-utils: Unify clock direction by clk_direction
I have observed some impacts on the STM32 SAI driver behavior.
To accommodate the change introduced by this commit, I added the property
"system-clock-direction-out" in the SAI device tree node.
The SAI nodes typically look as follows:
&sai2 {
sai2a: audio-controller@...0b004 {
#clock-cells = <0>;
clocks = <&rcc SAI2_K>;
clock-names = "sai_ck";
status = "okay";
sai2a_port: port {
sai2a_endpoint: endpoint {
mclk-fs = <256>;
system-clock-direction-out;
};
};
};
};
However, I noticed a change in the driver behavior:
* Before the change:
- Initialization:
simple_init_dai() -> set_sysclk(id=0, freq=sai_ck freq, dir=out)
Calls clk_set_rate_exclusive()
simple_util_shutdown() -> set_sysclk(id=0, freq=0, dir=out)
Calls clk_rate_exclusive_put() (releases the mclk clock)
Comments:
At initialization, the mclk rate is set with the kernel clock frequency.
- Runtime:
simple_util_hw_params() -> set_sysclk(id=0, freq=mclk freq, dir=out)
Comments:
At runtime, the mclk rate is set with the mclk clock frequency.
* After the change:
- Initialization:
simple_init_dai() -> set_sysclk(id=0, freq=sai_ck freq, dir=out)
Calls clk_set_rate_exclusive()
simple_util_shutdown() -> set_sysclk(id=0, freq=0, dir=in)
clk_rate_exclusive_put() NOT called (mclk clock is not released)
Comments:
The set_sysclk() is called with input direction, resulting in unbalanced
calls. This seems to be an unexpected behavior.
- Runtime:
simple_util_hw_params() -> set_sysclk(id=0, freq=mclk freq, dir=out)
This incorrect behavior made me realize that set_sysclk should not be
called when the frequency corresponds to the kernel clock frequency.
Here, the SAI driver needs a way to discriminate between the kernel clock
and the master clock.
I identified the following possibilities to achieve this:
- Check execution context:
Assuming the requested frequency is correct for mclk at runtime,
the execution context may be used as a discriminator.
The snd_soc_dai_stream_active() or snd_soc_card_is_instantiated() functions
can help determine the execution context.
For example, the following check can be added in STM32 SAI set_sysclk:
if (!snd_soc_card_is_instantiated(cpu_dai->component->card))
return 0;
This approach fixes the issue but looks more like a workaround.
- Check clock direction:
I expected the kernel clock to remain tagged as an input clock.
I am not sure what the correct behavior is yet.
This may have been a way to differentiate clocks in this particular case,
but I don't think it is a robust method anyway.
- Check clk_id:
This seems the most relevant way to identify clocks.
However, clk_id is still set to 0 in simple card set_sysclk calls,
So, it does not seem to be a valid option at this time.
---
sound/soc/stm/stm32_sai_sub.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 463a2b7d023b..0ae1eae2a59e 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -672,6 +672,14 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
+ /*
+ * The mclk rate is determined at runtime from the audio stream rate.
+ * Skip calls to the set_sysclk callback that are not relevant during the
+ * initialization phase.
+ */
+ if (!snd_soc_card_is_instantiated(cpu_dai->component->card))
+ return 0;
+
if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
SAI_XCR1_NODIV,
--
2.25.1
Powered by blists - more mailing lists