[PATCH 14/25] ASoC: meson: axg-pdm: introduce 'sysrate' property

From: Jan Dakinevich
Date: Thu Mar 14 2024 - 19:25:52 EST


This driver unconditionally set the rate of DSP system clock to 250MHz,
that on A1 SoC family causes reconfiguring of 'hifi_pll' clock to some
rate, that is multiple to 250MHz.

Further, when playback is activating 'hifi_pll' would be reconfigured
to another rate to produce audio clock like 12288000Hz. Both these rates
can't coexist on same parent.

To avoid the fight for 'hifi_pll' clock allow PDM controller to
configure its maximum sysrate through device tree. It will allow to
inherit 'sysclk' from another clock (i.e. 'fclk_div2') and isolate
'hifi_pll' from PDM influence.

Signed-off-by: Jan Dakinevich <jan.dakinevich@xxxxxxxxxxxxxxxxx>
---
sound/soc/meson/axg-pdm.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/sound/soc/meson/axg-pdm.c b/sound/soc/meson/axg-pdm.c
index d59050914d3c..a132444a51fb 100644
--- a/sound/soc/meson/axg-pdm.c
+++ b/sound/soc/meson/axg-pdm.c
@@ -94,6 +94,7 @@ struct axg_pdm {
struct clk *dclk;
struct clk *sysclk;
struct clk *pclk;
+ u32 sys_rate;
};

static void axg_pdm_enable(struct regmap *map)
@@ -172,10 +173,10 @@ static int axg_pdm_set_sysclk(struct axg_pdm *priv, unsigned int os,
* the requested sample rate. In this case, the sample pointer
* counter could overflow so set a lower system clock rate
*/
- if (sys_rate < priv->cfg->sys_rate)
+ if (sys_rate < priv->sys_rate)
return clk_set_rate(priv->sysclk, sys_rate);

- return clk_set_rate(priv->sysclk, priv->cfg->sys_rate);
+ return clk_set_rate(priv->sysclk, priv->sys_rate);
}

static int axg_pdm_set_sample_pointer(struct axg_pdm *priv)
@@ -386,7 +387,7 @@ static int axg_pdm_dai_probe(struct snd_soc_dai *dai)
* sysclk must be set and enabled as well to access the pdm registers
* Accessing the register w/o it will give a bus error.
*/
- ret = clk_set_rate(priv->sysclk, priv->cfg->sys_rate);
+ ret = clk_set_rate(priv->sysclk, priv->sys_rate);
if (ret) {
dev_err(dai->dev, "setting sysclk failed\n");
goto err_pclk;
@@ -623,6 +624,9 @@ static int axg_pdm_probe(struct platform_device *pdev)
if (IS_ERR(priv->sysclk))
return dev_err_probe(dev, PTR_ERR(priv->sysclk), "failed to get dclk\n");

+ if (device_property_read_u32(dev, "sysrate", &priv->sys_rate))
+ priv->sys_rate = priv->cfg->sys_rate;
+
return devm_snd_soc_register_component(dev, &axg_pdm_component_drv,
&axg_pdm_dai_drv, 1);
}
--
2.34.1