All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] ASoC: fsl_sai: Defer TERE until stream setup
@ 2026-10-19 22:28 Fabio Estevam
  2026-10-19 22:28 ` [PATCH 2/3] ASoC: fsl_sai: Stop BCLK after the last stream is freed Fabio Estevam
  2026-10-19 22:28 ` [PATCH 3/3] ASoC: fsl_sai: Select sleep pinctrl state during runtime suspend Fabio Estevam
  0 siblings, 2 replies; 3+ messages in thread
From: Fabio Estevam @ 2026-10-19 22:28 UTC (permalink / raw)
  To: broonie; +Cc: shengjiu.wang, linux-sound, Fabio Estevam

On i.MX8MP, TERE also enables MCLK output. Runtime resume sets it
before hw_params has configured the stream, so clocks can start from
stale register values.

In master mode, a custom board with a 400 MHz IPG clock drove BCLK
at 200 MHz before hw_params rewrote xCR2. On first open, reset xCR4
also drove frame sync at about 100 MHz. Later opens can select the
bus clock with DIV=0 and again drive BCLK prematurely.

Enable TERE at the end of hw_params after programming stream format
and clock settings. During runtime resume, restore TERE only when a
configured stream is being resumed.

Fixes: 3e4a82612998 ("ASoC: fsl_sai: MCLK bind with TX/RX enable bit")
Signed-off-by: Fabio Estevam <festevam@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d232c8f53061..51779d7f8bf8 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -799,6 +799,15 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
 	regmap_write(sai->regmap, FSL_SAI_xMR(tx),
 		     ~GENMASK_U32(min(channels, slots) - 1, 0));
 
+	/*
+	 * On i.MX8MP, TERE also enables the master clock output. Enable it
+	 * after hw_params has configured the stream to avoid briefly driving
+	 * clocks from stale register values.
+	 */
+	if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
+		regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
+				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+
 	return 0;
 }
 
@@ -1983,7 +1992,13 @@ static int fsl_sai_runtime_resume(struct device *dev)
 	if (ret)
 		goto disable_rx_clk;
 
-	if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
+	/*
+	 * A fresh stream has not configured its clock divider yet. Keep TERE
+	 * disabled until hw_params in that case; an already configured stream
+	 * needs it restored after a system suspend.
+	 */
+	if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
+	    sai->mclk_streams)
 		regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
 				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
 
-- 
2.43.0


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

* [PATCH 2/3] ASoC: fsl_sai: Stop BCLK after the last stream is freed
  2026-10-19 22:28 [PATCH 1/3] ASoC: fsl_sai: Defer TERE until stream setup Fabio Estevam
@ 2026-10-19 22:28 ` Fabio Estevam
  2026-10-19 22:28 ` [PATCH 3/3] ASoC: fsl_sai: Select sleep pinctrl state during runtime suspend Fabio Estevam
  1 sibling, 0 replies; 3+ messages in thread
From: Fabio Estevam @ 2026-10-19 22:28 UTC (permalink / raw)
  To: broonie; +Cc: shengjiu.wang, linux-sound, Fabio Estevam

On i.MX8MP, trigger stop leaves BCE set so MCLK remains available to
a codec. When the final stream is freed, hw_free disables MCLK, but
TERE and BCE can keep BCLK running from the newly selected clock
source, including an unconfigured bus clock.

Clear TERE and BCE once no configured or active stream needs the
clock. This preserves MCLK between trigger stop and hw_free.

The premature clock output was reproduced on a custom i.MX8MP board.

Fixes: 197c53c8ecb3 ("ASoC: fsl_sai: Don't disable bitclock for i.MX8MP")
Signed-off-by: Fabio Estevam <festevam@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 51779d7f8bf8..a135b3da37cf 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -851,6 +851,16 @@ static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
 		}
 	}
 
+	/*
+	 * Keep MCLK available until the last stream is freed, as it may be
+	 * needed by a codec. Once no stream uses it, stop TERE and BCE too;
+	 * otherwise BCLK can continue from the clock source selected later.
+	 */
+	if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
+	    !sai->mclk_streams && snd_soc_dai_active(cpu_dai) <= 1)
+		regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
+				   FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE, 0);
+
 	return 0;
 }
 
-- 
2.43.0


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

* [PATCH 3/3] ASoC: fsl_sai: Select sleep pinctrl state during runtime suspend
  2026-10-19 22:28 [PATCH 1/3] ASoC: fsl_sai: Defer TERE until stream setup Fabio Estevam
  2026-10-19 22:28 ` [PATCH 2/3] ASoC: fsl_sai: Stop BCLK after the last stream is freed Fabio Estevam
@ 2026-10-19 22:28 ` Fabio Estevam
  1 sibling, 0 replies; 3+ messages in thread
From: Fabio Estevam @ 2026-10-19 22:28 UTC (permalink / raw)
  To: broonie; +Cc: shengjiu.wang, linux-sound, Fabio Estevam

When runtime suspended, the SAI can leave its outputs at their last
levels. If a connected device is unpowered, those signals can source
current through its input protection circuitry.

Select the sleep pinctrl state after gating the clocks, and restore the
default state before enabling them on runtime resume. Devices without
a sleep state continue to use their existing pin configuration.

The pin-state issue was reproduced on a custom i.MX8MP board.

Signed-off-by: Fabio Estevam <festevam@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index a135b3da37cf..ad21bd3b8a5d 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1959,6 +1959,7 @@ static int fsl_sai_runtime_suspend(struct device *dev)
 		cpu_latency_qos_remove_request(&sai->pm_qos_req);
 
 	regcache_cache_only(sai->regmap, true);
+	pinctrl_pm_select_sleep_state(dev);
 
 	return 0;
 }
@@ -1969,6 +1970,8 @@ static int fsl_sai_runtime_resume(struct device *dev)
 	unsigned int ofs = sai->soc_data->reg_offset;
 	int ret;
 
+	pinctrl_pm_select_default_state(dev);
+
 	ret = clk_prepare_enable(sai->bus_clk);
 	if (ret) {
 		dev_err(dev, "failed to enable bus clock: %d\n", ret);
-- 
2.43.0


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

end of thread, other threads:[~2026-10-19 22:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-19 22:28 [PATCH 1/3] ASoC: fsl_sai: Defer TERE until stream setup Fabio Estevam
2026-10-19 22:28 ` [PATCH 2/3] ASoC: fsl_sai: Stop BCLK after the last stream is freed Fabio Estevam
2026-10-19 22:28 ` [PATCH 3/3] ASoC: fsl_sai: Select sleep pinctrl state during runtime suspend Fabio Estevam

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.