Message ID | 20241226162234.40141-4-marex@denx.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2,1/4] dt-bindings: clock: fsl-sai: Document i.MX8M support | expand |
On 12/30/24 2:28 AM, Peng Fan wrote: [...] >> static int fsl_sai_clk_probe(struct platform_device *pdev) >> { >> struct device *dev = &pdev->dev; >> const struct fsl_sai_data *data = device_get_match_data(dev); >> - struct fsl_sai_clk *sai_clk; >> struct clk_parent_data pdata = { .index = 0 }; >> + struct fsl_sai_clk *sai_clk; >> + struct clk *clk_bus; >> void __iomem *base; >> struct clk_hw *hw; >> >> @@ -47,39 +65,74 @@ static int fsl_sai_clk_probe(struct platform_device *pdev) >> if (IS_ERR(base)) >> return PTR_ERR(base); >> >> + clk_bus = devm_clk_get_enabled(dev, "bus"); >> + if (IS_ERR(clk_bus)) >> + return PTR_ERR(clk_bus); >> + > > This only applies to i.MX? I think so ... what am I missing , some Vybrid / Layerscape detail ?
On Thu, Dec 26, 2024 at 05:22:24PM +0100, Marek Vasut wrote: >The driver currently supports generating BCLK. There are systems which >require generation of MCLK instead. Register new MCLK clock and handle >clock-cells = <1> to differentiate between BCLK and MCLK. In case of a >legacy system with clock-cells = <0>, the driver behaves as before, i.e. >always returns BCLK. > >Signed-off-by: Marek Vasut <marex@denx.de> >--- >Cc: Conor Dooley <conor+dt@kernel.org> >Cc: Fabio Estevam <festevam@gmail.com> >Cc: Jaroslav Kysela <perex@perex.cz> >Cc: Krzysztof Kozlowski <krzk+dt@kernel.org> >Cc: Liam Girdwood <lgirdwood@gmail.com> >Cc: Mark Brown <broonie@kernel.org> >Cc: Michael Turquette <mturquette@baylibre.com> >Cc: Michael Walle <michael@walle.cc> >Cc: Nicolin Chen <nicoleotsuka@gmail.com> >Cc: Rob Herring <robh@kernel.org> >Cc: Shengjiu Wang <shengjiu.wang@gmail.com> >Cc: Stephen Boyd <sboyd@kernel.org> >Cc: Takashi Iwai <tiwai@suse.com> >Cc: Xiubo Li <Xiubo.Lee@gmail.com> >Cc: devicetree@vger.kernel.org >Cc: linux-clk@vger.kernel.org >Cc: linux-sound@vger.kernel.org >--- >V2: No change >--- > drivers/clk/clk-fsl-sai.c | 81 ++++++++++++++++++++++++++++++++------- > 1 file changed, 67 insertions(+), 14 deletions(-) > >diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c >index 628e53a3a26fa..0f8e2f2662d87 100644 >--- a/drivers/clk/clk-fsl-sai.c >+++ b/drivers/clk/clk-fsl-sai.c >@@ -7,6 +7,7 @@ > > #include <linux/module.h> > #include <linux/platform_device.h> >+#include <linux/clk.h> > #include <linux/clk-provider.h> > #include <linux/err.h> > #include <linux/of.h> >@@ -15,27 +16,44 @@ > > #define I2S_CSR 0x00 > #define I2S_CR2 0x08 >+#define I2S_MCR 0x100 > #define CSR_BCE_BIT 28 >+#define CSR_TE_BIT 31 > #define CR2_BCD BIT(24) > #define CR2_DIV_SHIFT 0 > #define CR2_DIV_WIDTH 8 >+#define MCR_MOE BIT(30) > > struct fsl_sai_clk { >- struct clk_divider div; >- struct clk_gate gate; >+ struct clk_divider bclk_div; >+ struct clk_divider mclk_div; >+ struct clk_gate bclk_gate; >+ struct clk_gate mclk_gate; >+ struct clk_hw *bclk_hw; >+ struct clk_hw *mclk_hw; > spinlock_t lock; > }; > > struct fsl_sai_data { > unsigned int offset; /* Register offset */ >+ bool have_mclk; /* Have MCLK control */ > }; > >+static struct clk_hw * >+fsl_sai_of_clk_get(struct of_phandle_args *clkspec, void *data) >+{ >+ struct fsl_sai_clk *sai_clk = data; >+ >+ return clkspec->args[0] ? sai_clk->mclk_hw : sai_clk->bclk_hw; >+} >+ > static int fsl_sai_clk_probe(struct platform_device *pdev) > { > struct device *dev = &pdev->dev; > const struct fsl_sai_data *data = device_get_match_data(dev); >- struct fsl_sai_clk *sai_clk; > struct clk_parent_data pdata = { .index = 0 }; >+ struct fsl_sai_clk *sai_clk; >+ struct clk *clk_bus; > void __iomem *base; > struct clk_hw *hw; > >@@ -47,39 +65,74 @@ static int fsl_sai_clk_probe(struct platform_device *pdev) > if (IS_ERR(base)) > return PTR_ERR(base); > >+ clk_bus = devm_clk_get_enabled(dev, "bus"); >+ if (IS_ERR(clk_bus)) >+ return PTR_ERR(clk_bus); >+ This only applies to i.MX? > spin_lock_init(&sai_clk->lock); > Regards, Peng
Hi Marek, On Thu Dec 26, 2024 at 5:22 PM CET, Marek Vasut wrote: > The driver currently supports generating BCLK. I'd say the driver supports generating *any* clock on the BCLK pin. It's not necessarily the BCLK clock. I.e. on the board where this is used, this is the clock with a given frequency sourcing the PLL in the audio codec. > There are systems which require generation of MCLK instead. You mean systems that use the MCLK pin instead? ..Which is the normal use case for this pin. This driver was created because the LS1028A doesn't have a MCLK pin, so we've "misused" the BCLK pin, with the restriction that only integer dividers are possible. I haven't looked at the datasheet, but doesn't the MCLK has a PLL which could generate any frequency? Also I'd expect that the imx SoCs already supports the MCLK for audio applications. Isn't that the case? > Register new MCLK clock and handle > clock-cells = <1> to differentiate between BCLK and MCLK. In case of a > legacy system with clock-cells = <0>, the driver behaves as before, i.e. > always returns BCLK. -michael
On 12/30/24 8:51 AM, Michael Walle wrote: > Hi Marek, Hi, > On Thu Dec 26, 2024 at 5:22 PM CET, Marek Vasut wrote: >> The driver currently supports generating BCLK. > > I'd say the driver supports generating *any* clock on the BCLK pin. The clock are coming out of the SAI 'BCLK' output and are controlled by the SAI BCLK control bits. Of course, it is possible to feed arbitrary upstream clock into the SAI and have those exposed on the BCLK pin. I'll try to reword the commit message to make that clearer. > It's not necessarily the BCLK clock. I.e. on the board where this is > used, this is the clock with a given frequency sourcing the PLL in > the audio codec. Right >> There are systems which require generation of MCLK instead. > > You mean systems that use the MCLK pin instead? Yes > ..Which is the > normal use case for this pin. This driver was created because the > LS1028A doesn't have a MCLK pin, so we've "misused" the BCLK pin, > with the restriction that only integer dividers are possible. I have a system that is wired a bit unfortunately, I need to source codec clock, where the codec is the clock consumer and needs to be able to control the clock (SGTL5000). SAI MCLK is the only way I can get them out of the pin I need, hence this patch. > I > haven't looked at the datasheet, but doesn't the MCLK has a PLL > which could generate any frequency? Audio PLL , sure. > Also I'd expect that the imx > SoCs already supports the MCLK for audio applications. Isn't that > the case? That does not work if the MCLK has to be enabled/disabled by the MCLK clock consumer . [...]
Hi, > > ..Which is the > > normal use case for this pin. This driver was created because the > > LS1028A doesn't have a MCLK pin, so we've "misused" the BCLK pin, > > with the restriction that only integer dividers are possible. > > I have a system that is wired a bit unfortunately, I need to source > codec clock, where the codec is the clock consumer and needs to be able > to control the clock (SGTL5000). SAI MCLK is the only way I can get them > out of the pin I need, hence this patch. Which is also the default case, no? > > Also I'd expect that the imx > > SoCs already supports the MCLK for audio applications. Isn't that > > the case? > > That does not work if the MCLK has to be enabled/disabled by the MCLK > clock consumer . Why's that? Don't get me wrong. I don't have anything against this patch, I'm just confused, why that isn't already working with the current MCLK driver as this seems to be the usual requirements. -michael
On 1/2/25 10:58 AM, Michael Walle wrote: > Hi, Hi, >>> ..Which is the >>> normal use case for this pin. This driver was created because the >>> LS1028A doesn't have a MCLK pin, so we've "misused" the BCLK pin, >>> with the restriction that only integer dividers are possible. >> >> I have a system that is wired a bit unfortunately, I need to source >> codec clock, where the codec is the clock consumer and needs to be able >> to control the clock (SGTL5000). SAI MCLK is the only way I can get them >> out of the pin I need, hence this patch. > > Which is also the default case, no? Not quite, there is a difference. If SAI (audio driver) is used to control the MCLK enablement, then MCLK clock is not always enabled, and it is not necessarily enabled when the codec may need the clock to be enabled. There is also no way for the codec node to specify phandle to clock provider in DT, because the SAI (audio driver) is not clock provider. If SAI (clock driver) is used to control the MCLK enablement, then MCLK clock is enabled when the codec needs the clock enabled, because the codec is the clock consumer and the SAI (clock driver) is the clock provider, and the codec driver can request the clock to be enabled when needed. There is also the usual phandle to clock provider in DT, because the SAI (clock driver) is clock provider. >>> Also I'd expect that the imx >>> SoCs already supports the MCLK for audio applications. Isn't that >>> the case? >> >> That does not work if the MCLK has to be enabled/disabled by the MCLK >> clock consumer . > > Why's that? > > Don't get me wrong. I don't have anything against this patch, I'm > just confused, why that isn't already working with the current MCLK > driver as this seems to be the usual requirements. Which current MCLK driver, the SAI in audio driver role ? Does the paragraph in the middle of this email possibly answer this question ?
On Thu Jan 2, 2025 at 2:34 PM CET, Marek Vasut wrote: > On 1/2/25 10:58 AM, Michael Walle wrote: > > Hi, > > Hi, > > >>> ..Which is the > >>> normal use case for this pin. This driver was created because the > >>> LS1028A doesn't have a MCLK pin, so we've "misused" the BCLK pin, > >>> with the restriction that only integer dividers are possible. > >> > >> I have a system that is wired a bit unfortunately, I need to source > >> codec clock, where the codec is the clock consumer and needs to be able > >> to control the clock (SGTL5000). SAI MCLK is the only way I can get them > >> out of the pin I need, hence this patch. > > > > Which is also the default case, no? > > Not quite, there is a difference. > > If SAI (audio driver) is used to control the MCLK enablement, then MCLK > clock is not always enabled, and it is not necessarily enabled when the > codec may need the clock to be enabled. There is also no way for the > codec node to specify phandle to clock provider in DT, because the SAI > (audio driver) is not clock provider. > > If SAI (clock driver) is used to control the MCLK enablement, then MCLK > clock is enabled when the codec needs the clock enabled, because the > codec is the clock consumer and the SAI (clock driver) is the clock > provider, and the codec driver can request the clock to be enabled when > needed. There is also the usual phandle to clock provider in DT, because > the SAI (clock driver) is clock provider. > > >>> Also I'd expect that the imx > >>> SoCs already supports the MCLK for audio applications. Isn't that > >>> the case? > >> > >> That does not work if the MCLK has to be enabled/disabled by the MCLK > >> clock consumer . > > > > Why's that? > > > > Don't get me wrong. I don't have anything against this patch, I'm > > just confused, why that isn't already working with the current MCLK > > driver as this seems to be the usual requirements. > Which current MCLK driver, the SAI in audio driver role ? Yes. > Does the paragraph in the middle of this email possibly answer this > question ? Yes thanks! For reference, IMHO the correct way to do it would be to add clock provider support to the original SAI, esp. because both drivers are mutually exclusive. But I'm fine to add MCLK support for this driver for hardware which has a spare SAI and to just use that as a MCLK source. Acked-by: Michael Walle <mwalle@kernel.org> -michael
diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c index 628e53a3a26fa..0f8e2f2662d87 100644 --- a/drivers/clk/clk-fsl-sai.c +++ b/drivers/clk/clk-fsl-sai.c @@ -7,6 +7,7 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/err.h> #include <linux/of.h> @@ -15,27 +16,44 @@ #define I2S_CSR 0x00 #define I2S_CR2 0x08 +#define I2S_MCR 0x100 #define CSR_BCE_BIT 28 +#define CSR_TE_BIT 31 #define CR2_BCD BIT(24) #define CR2_DIV_SHIFT 0 #define CR2_DIV_WIDTH 8 +#define MCR_MOE BIT(30) struct fsl_sai_clk { - struct clk_divider div; - struct clk_gate gate; + struct clk_divider bclk_div; + struct clk_divider mclk_div; + struct clk_gate bclk_gate; + struct clk_gate mclk_gate; + struct clk_hw *bclk_hw; + struct clk_hw *mclk_hw; spinlock_t lock; }; struct fsl_sai_data { unsigned int offset; /* Register offset */ + bool have_mclk; /* Have MCLK control */ }; +static struct clk_hw * +fsl_sai_of_clk_get(struct of_phandle_args *clkspec, void *data) +{ + struct fsl_sai_clk *sai_clk = data; + + return clkspec->args[0] ? sai_clk->mclk_hw : sai_clk->bclk_hw; +} + static int fsl_sai_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct fsl_sai_data *data = device_get_match_data(dev); - struct fsl_sai_clk *sai_clk; struct clk_parent_data pdata = { .index = 0 }; + struct fsl_sai_clk *sai_clk; + struct clk *clk_bus; void __iomem *base; struct clk_hw *hw; @@ -47,39 +65,74 @@ static int fsl_sai_clk_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); + clk_bus = devm_clk_get_enabled(dev, "bus"); + if (IS_ERR(clk_bus)) + return PTR_ERR(clk_bus); + spin_lock_init(&sai_clk->lock); - sai_clk->gate.reg = base + data->offset + I2S_CSR; - sai_clk->gate.bit_idx = CSR_BCE_BIT; - sai_clk->gate.lock = &sai_clk->lock; + sai_clk->bclk_gate.reg = base + data->offset + I2S_CSR; + sai_clk->bclk_gate.bit_idx = CSR_BCE_BIT; + sai_clk->bclk_gate.lock = &sai_clk->lock; - sai_clk->div.reg = base + data->offset + I2S_CR2; - sai_clk->div.shift = CR2_DIV_SHIFT; - sai_clk->div.width = CR2_DIV_WIDTH; - sai_clk->div.lock = &sai_clk->lock; + sai_clk->bclk_div.reg = base + data->offset + I2S_CR2; + sai_clk->bclk_div.shift = CR2_DIV_SHIFT; + sai_clk->bclk_div.width = CR2_DIV_WIDTH; + sai_clk->bclk_div.lock = &sai_clk->lock; /* set clock direction, we are the BCLK master */ writel(CR2_BCD, base + data->offset + I2S_CR2); - hw = devm_clk_hw_register_composite_pdata(dev, dev->of_node->name, + hw = devm_clk_hw_register_composite_pdata(dev, "BCLK", &pdata, 1, NULL, NULL, - &sai_clk->div.hw, + &sai_clk->bclk_div.hw, &clk_divider_ops, - &sai_clk->gate.hw, + &sai_clk->bclk_gate.hw, &clk_gate_ops, CLK_SET_RATE_GATE); if (IS_ERR(hw)) return PTR_ERR(hw); - return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); + sai_clk->bclk_hw = hw; + + if (data->have_mclk) { + sai_clk->mclk_gate.reg = base + data->offset + I2S_CSR; + sai_clk->mclk_gate.bit_idx = CSR_TE_BIT; + sai_clk->mclk_gate.lock = &sai_clk->lock; + + sai_clk->mclk_div.reg = base + I2S_MCR; + sai_clk->mclk_div.shift = CR2_DIV_SHIFT; + sai_clk->mclk_div.width = CR2_DIV_WIDTH; + sai_clk->mclk_div.lock = &sai_clk->lock; + + pdata.index = 1; /* MCLK1 */ + hw = devm_clk_hw_register_composite_pdata(dev, "MCLK", + &pdata, 1, NULL, NULL, + &sai_clk->mclk_div.hw, + &clk_divider_ops, + &sai_clk->mclk_gate.hw, + &clk_gate_ops, + CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + sai_clk->mclk_hw = hw; + + /* set clock direction, we are the MCLK output */ + writel(MCR_MOE, base + I2S_MCR); + } + + return devm_of_clk_add_hw_provider(dev, fsl_sai_of_clk_get, sai_clk); } static const struct fsl_sai_data fsl_sai_vf610_data = { .offset = 0, + .have_mclk = false, }; static const struct fsl_sai_data fsl_sai_imx8mq_data = { .offset = 8, + .have_mclk = true, }; static const struct of_device_id of_fsl_sai_clk_ids[] = {
The driver currently supports generating BCLK. There are systems which require generation of MCLK instead. Register new MCLK clock and handle clock-cells = <1> to differentiate between BCLK and MCLK. In case of a legacy system with clock-cells = <0>, the driver behaves as before, i.e. always returns BCLK. Signed-off-by: Marek Vasut <marex@denx.de> --- Cc: Conor Dooley <conor+dt@kernel.org> Cc: Fabio Estevam <festevam@gmail.com> Cc: Jaroslav Kysela <perex@perex.cz> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org> Cc: Liam Girdwood <lgirdwood@gmail.com> Cc: Mark Brown <broonie@kernel.org> Cc: Michael Turquette <mturquette@baylibre.com> Cc: Michael Walle <michael@walle.cc> Cc: Nicolin Chen <nicoleotsuka@gmail.com> Cc: Rob Herring <robh@kernel.org> Cc: Shengjiu Wang <shengjiu.wang@gmail.com> Cc: Stephen Boyd <sboyd@kernel.org> Cc: Takashi Iwai <tiwai@suse.com> Cc: Xiubo Li <Xiubo.Lee@gmail.com> Cc: devicetree@vger.kernel.org Cc: linux-clk@vger.kernel.org Cc: linux-sound@vger.kernel.org --- V2: No change --- drivers/clk/clk-fsl-sai.c | 81 ++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 14 deletions(-)