Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH v2 0/2] ASoC: simple-card: make sysclk ordering configurable
@ 2026-02-10 16:45 Stefano Radaelli
  2026-02-10 16:45 ` [PATCH v2 1/2] dt-bindings: sound: simple-card: add sysclk-cpu-first flag Stefano Radaelli
  2026-02-10 16:45 ` [PATCH v2 2/2] ASoC: simple-card-utils: add selectable sysclk ordering Stefano Radaelli
  0 siblings, 2 replies; 5+ messages in thread
From: Stefano Radaelli @ 2026-02-10 16:45 UTC (permalink / raw)
  To: Kuninori Morimoto, linux-sound, linux-kernel
  Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jaroslav Kysela, Takashi Iwai, alexander.h,
	pierluigi.p, Stefano Radaelli

This patch series addresses an issue in simple-audio-card where the
ordering of sysclk configuration between CPU and codec DAIs can affect
the initial playback behaviour on some platforms.

Some CPU DAIs finalize the MCLK rate as part of their set_sysclk()
callback. If the codec sysclk is configured before the CPU DAI applies
the final MCLK rate, the codec may base its internal clocking on a
non-final MCLK value, resulting in incorrect clocking on the first
playback after boot.

This was observed on i.MX95 systems using fsl_sai, but the issue is
generic and can affect any setup where the CPU DAI adjusts the MCLK rate
in set_sysclk().

Instead of changing the ordering unconditionally, this series keeps the
existing default behaviour (codec-first) and introduces a DT flag that
allows selecting CPU-first sysclk ordering where required. This makes
the behaviour configurable on a per-card or per-link basis while
avoiding regressions on existing systems.

Patch 1 documents the new DT binding.
Patch 2 implements the selectable sysclk ordering in simple-audio-card.

v2:
- Do not change the default sysclk ordering
- Make the ordering selectable via DT flag
- Add DT binding documentation

v1:
Link: https://patchwork.kernel.org/project/alsa-devel/patch/20260206134014.143057-1-stefano.r@variscite.com/

Stefano Radaelli (2):
  dt-bindings: sound: simple-card: add sysclk-cpu-first flag
  ASoC: simple-card-utils: add selectable sysclk ordering

 .../bindings/sound/simple-card.yaml           | 11 ++++++
 include/sound/simple_card_utils.h             |  1 +
 sound/soc/generic/simple-card-utils.c         | 39 +++++++++++++------
 sound/soc/generic/simple-card.c               |  7 ++++
 4 files changed, 47 insertions(+), 11 deletions(-)


base-commit: b7ff7151e653aa296ab6c5495b2c1ab7c21eb250
-- 
2.47.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] dt-bindings: sound: simple-card: add sysclk-cpu-first flag
  2026-02-10 16:45 [PATCH v2 0/2] ASoC: simple-card: make sysclk ordering configurable Stefano Radaelli
@ 2026-02-10 16:45 ` Stefano Radaelli
  2026-02-11  6:23   ` Krzysztof Kozlowski
  2026-02-10 16:45 ` [PATCH v2 2/2] ASoC: simple-card-utils: add selectable sysclk ordering Stefano Radaelli
  1 sibling, 1 reply; 5+ messages in thread
From: Stefano Radaelli @ 2026-02-10 16:45 UTC (permalink / raw)
  To: Kuninori Morimoto, linux-sound, linux-kernel
  Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jaroslav Kysela, Takashi Iwai, alexander.h,
	pierluigi.p, Stefano Radaelli

From: Stefano Radaelli <stefano.r@variscite.com>

The simple-audio-card driver can program sysclk for CPU and codec DAIs
during hw_params. Some setups require calling the CPU DAI sysclk first
so that the codec sees the final MCLK rate.

Document a new boolean DT flag, sysclk-cpu-first, which allows selecting
CPU-first sysclk ordering where needed. The property is supported both
as a top-level simple-audio-card property (prefixed) and on dai-link
subnodes (non-prefixed).

Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
---
 .../devicetree/bindings/sound/simple-card.yaml        | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/simple-card.yaml b/Documentation/devicetree/bindings/sound/simple-card.yaml
index 533d0a1da56e..ddad440636be 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.yaml
+++ b/Documentation/devicetree/bindings/sound/simple-card.yaml
@@ -35,6 +35,13 @@ definitions:
     description: see tdm-slot.txt.
     $ref: /schemas/types.yaml#/definitions/uint32
 
+  sysclk-cpu-first:
+    description:
+      When mclk-fs is used, configure CPU DAI sysclk before codec DAI sysclk
+      so the codec sees the final MCLK rate.
+      This property only affects the mclk-fs code path.
+    $ref: /schemas/types.yaml#/definitions/flag
+
   system-clock-frequency:
     description: |
       If a clock is specified and a multiplication factor is given with
@@ -194,6 +201,8 @@ properties:
     $ref: "#/definitions/format"
   simple-audio-card,mclk-fs:
     $ref: "#/definitions/mclk-fs"
+  simple-audio-card,sysclk-cpu-first:
+    $ref: "#/definitions/sysclk-cpu-first"
   simple-audio-card,aux-devs:
     $ref: "#/definitions/aux-devs"
   simple-audio-card,additional-devs:
@@ -251,6 +260,8 @@ patternProperties:
         $ref: "#/definitions/format"
       mclk-fs:
         $ref: "#/definitions/mclk-fs"
+      sysclk-cpu-first:
+        $ref: "#/definitions/sysclk-cpu-first"
       aux-devs:
         $ref: "#/definitions/aux-devs"
       convert-rate:
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] ASoC: simple-card-utils: add selectable sysclk ordering
  2026-02-10 16:45 [PATCH v2 0/2] ASoC: simple-card: make sysclk ordering configurable Stefano Radaelli
  2026-02-10 16:45 ` [PATCH v2 1/2] dt-bindings: sound: simple-card: add sysclk-cpu-first flag Stefano Radaelli
@ 2026-02-10 16:45 ` Stefano Radaelli
  1 sibling, 0 replies; 5+ messages in thread
From: Stefano Radaelli @ 2026-02-10 16:45 UTC (permalink / raw)
  To: Kuninori Morimoto, linux-sound, linux-kernel
  Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jaroslav Kysela, Takashi Iwai, alexander.h,
	pierluigi.p, Stefano Radaelli

From: Stefano Radaelli <stefano.r@variscite.com>

When simple-audio-card programs sysclk for CPU and codec DAIs during
hw_params, the ordering of these calls can matter on some platforms.

Some CPU DAIs apply the final MCLK rate as part of their set_sysclk()
callback (for example by changing the underlying clock rate via
clk_set_rate()). If the codec sysclk is configured before the CPU DAI
applies the final MCLK rate, the codec may configure its internal
clocking based on a non-final MCLK value, leading to an incorrect
clocking state on the first playback after boot.

This behaviour was observed on i.MX95 systems using fsl_sai with
downstream kernels, but the issue is generic and can affect any setup
where the CPU DAI finalizes the MCLK rate in set_sysclk().

A reproducible symptom is that the first playback runs at the wrong
speed, while subsequent playbacks work correctly.

Keep the existing default behaviour (codec sysclk configured before
CPU sysclk) to avoid regressions, and add a DT flag that allows
selecting CPU-first sysclk ordering when needed.

Example setup:
  - CPU DAI: fsl_sai (i.MX95)
  - Codec: wm8904

Reproducer:
  aplay -D hw:wm8904audio /home/Front_Center_8k.wav

Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
---
 include/sound/simple_card_utils.h     |  1 +
 sound/soc/generic/simple-card-utils.c | 39 +++++++++++++++++++--------
 sound/soc/generic/simple-card.c       |  7 +++++
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 69a9c9c4d0e9..60ab4df8e954 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -63,6 +63,7 @@ struct simple_util_priv {
 		struct snd_soc_codec_conf *codec_conf;
 		struct prop_nums num;
 		unsigned int mclk_fs;
+		bool sysclk_cpu_first;
 	} *dai_props;
 	struct simple_util_jack hp_jack;
 	struct simple_util_jack mic_jack;
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index bdc02e85b089..f5b851e7782d 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -501,18 +501,35 @@ int simple_util_hw_params(struct snd_pcm_substream *substream,
 				goto end;
 		}
 
-		for_each_rtd_codec_dais(rtd, i, sdai) {
-			pdai = simple_props_to_dai_codec(props, i);
-			ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
-			if (ret && ret != -ENOTSUPP)
-				goto end;
-		}
+		if (props->sysclk_cpu_first) {
+			for_each_rtd_cpu_dais(rtd, i, sdai) {
+				pdai = simple_props_to_dai_cpu(props, i);
+				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
+				if (ret && ret != -ENOTSUPP)
+					goto end;
+			}
 
-		for_each_rtd_cpu_dais(rtd, i, sdai) {
-			pdai = simple_props_to_dai_cpu(props, i);
-			ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
-			if (ret && ret != -ENOTSUPP)
-				goto end;
+			for_each_rtd_codec_dais(rtd, i, sdai) {
+				pdai = simple_props_to_dai_codec(props, i);
+				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
+				if (ret && ret != -ENOTSUPP)
+					goto end;
+			}
+		/* default: codec first */
+		} else {
+			for_each_rtd_codec_dais(rtd, i, sdai) {
+				pdai = simple_props_to_dai_codec(props, i);
+				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
+				if (ret && ret != -ENOTSUPP)
+					goto end;
+			}
+
+			for_each_rtd_cpu_dais(rtd, i, sdai) {
+				pdai = simple_props_to_dai_cpu(props, i);
+				ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction);
+				if (ret && ret != -ENOTSUPP)
+					goto end;
+			}
 		}
 	}
 
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 5af6d1b308f2..a16ead577f50 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -188,6 +188,7 @@ static int simple_link_init(struct simple_util_priv *priv,
 	enum snd_soc_trigger_order trigger_start = SND_SOC_TRIGGER_ORDER_DEFAULT;
 	enum snd_soc_trigger_order trigger_stop  = SND_SOC_TRIGGER_ORDER_DEFAULT;
 	bool playback_only = 0, capture_only = 0;
+	bool cpu_first = false;
 	int ret;
 
 	ret = simple_util_parse_daifmt(dev, node, codec,
@@ -209,6 +210,12 @@ static int simple_link_init(struct simple_util_priv *priv,
 	of_property_read_u32(codec,		"mclk-fs", &dai_props->mclk_fs);
 	of_property_read_u32(codec,	PREFIX	"mclk-fs", &dai_props->mclk_fs);
 
+	cpu_first |= of_property_read_bool(top,		"sysclk-cpu-first");
+	cpu_first |= of_property_read_bool(top,	PREFIX	"sysclk-cpu-first");
+	cpu_first |= of_property_read_bool(node,	"sysclk-cpu-first");
+	cpu_first |= of_property_read_bool(node, PREFIX	"sysclk-cpu-first");
+	dai_props->sysclk_cpu_first = cpu_first;
+
 	graph_util_parse_trigger_order(priv, top,	&trigger_start, &trigger_stop);
 	graph_util_parse_trigger_order(priv, node,	&trigger_start, &trigger_stop);
 	graph_util_parse_trigger_order(priv, cpu,	&trigger_start, &trigger_stop);
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] dt-bindings: sound: simple-card: add sysclk-cpu-first flag
  2026-02-10 16:45 ` [PATCH v2 1/2] dt-bindings: sound: simple-card: add sysclk-cpu-first flag Stefano Radaelli
@ 2026-02-11  6:23   ` Krzysztof Kozlowski
  2026-02-11  9:18     ` Stefano Radaelli
  0 siblings, 1 reply; 5+ messages in thread
From: Krzysztof Kozlowski @ 2026-02-11  6:23 UTC (permalink / raw)
  To: Stefano Radaelli, Kuninori Morimoto, linux-sound, linux-kernel
  Cc: Mark Brown, Liam Girdwood, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jaroslav Kysela, Takashi Iwai, alexander.h,
	pierluigi.p, Stefano Radaelli

On 10/02/2026 17:45, Stefano Radaelli wrote:
> From: Stefano Radaelli <stefano.r@variscite.com>
> 
> The simple-audio-card driver can program sysclk for CPU and codec DAIs
> during hw_params. Some setups require calling the CPU DAI sysclk first
> so that the codec sees the final MCLK rate.
> 
> Document a new boolean DT flag, sysclk-cpu-first, which allows selecting
> CPU-first sysclk ordering where needed. The property is supported both
> as a top-level simple-audio-card property (prefixed) and on dai-link
> subnodes (non-prefixed).

Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.

Please kindly resend and include all necessary To/Cc entries.

> 
> Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
> ---
>  .../devicetree/bindings/sound/simple-card.yaml        | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/simple-card.yaml b/Documentation/devicetree/bindings/sound/simple-card.yaml
> index 533d0a1da56e..ddad440636be 100644
> --- a/Documentation/devicetree/bindings/sound/simple-card.yaml
> +++ b/Documentation/devicetree/bindings/sound/simple-card.yaml
> @@ -35,6 +35,13 @@ definitions:
>      description: see tdm-slot.txt.
>      $ref: /schemas/types.yaml#/definitions/uint32
>  
> +  sysclk-cpu-first:
> +    description:
> +      When mclk-fs is used, configure CPU DAI sysclk before codec DAI sysclk
> +      so the codec sees the final MCLK rate.
> +      This property only affects the mclk-fs code path.

You described the desired Linux feature or behavior, not the actual
hardware. The bindings are about the latter, so instead you need to
rephrase the property and its description to match actual hardware
capabilities/features/configuration etc.


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] dt-bindings: sound: simple-card: add sysclk-cpu-first flag
  2026-02-11  6:23   ` Krzysztof Kozlowski
@ 2026-02-11  9:18     ` Stefano Radaelli
  0 siblings, 0 replies; 5+ messages in thread
From: Stefano Radaelli @ 2026-02-11  9:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Kuninori Morimoto, linux-sound, linux-kernel, Mark Brown,
	Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jaroslav Kysela, Takashi Iwai, alexander.h, pierluigi.p,
	Stefano Radaelli

Hi Krzysztof,
> 
> You described the desired Linux feature or behavior, not the actual
> hardware. The bindings are about the latter, so instead you need to
> rephrase the property and its description to match actual hardware
> capabilities/features/configuration etc.
> 

thanks for pointing this out.

After re-reading the binding and thinking about it again, I agree with you.
The proposed property describes a Linux driver policy (sysclk programming
order) rather than a hardware capability or configuration, so it does not
really fit the DT binding model.

I'll drop the DT binding part for now and reconsider how this should be
handled on the driver side instead.

If you have suggestions on a more appropriate direction for this kind of
configuration, I'd be happy to hear your opinion.

Best regards,
Stefano

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-02-11  9:18 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-10 16:45 [PATCH v2 0/2] ASoC: simple-card: make sysclk ordering configurable Stefano Radaelli
2026-02-10 16:45 ` [PATCH v2 1/2] dt-bindings: sound: simple-card: add sysclk-cpu-first flag Stefano Radaelli
2026-02-11  6:23   ` Krzysztof Kozlowski
2026-02-11  9:18     ` Stefano Radaelli
2026-02-10 16:45 ` [PATCH v2 2/2] ASoC: simple-card-utils: add selectable sysclk ordering Stefano Radaelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox