linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Add runtime PM for SAI digital audio interface
@ 2019-04-22 19:02 Daniel Baluta
  2019-04-22 19:02 ` [PATCH v3 1/3] ASoC: fsl_sai: Update is_slave_mode with correct value Daniel Baluta
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Daniel Baluta @ 2019-04-22 19:02 UTC (permalink / raw)
  To: broonie
  Cc: S.j. Wang, lgirdwood, timur, Xiubo.Lee, festevam, perex, tiwai,
	alsa-devel, linuxppc-dev, linux-kernel, dl-linux-imx,
	Daniel Baluta

First patch fixes a bug by correctly setting is_slave_mode, then
second patch adds support for runtime PM and finally 3rd patch moves
clock handling from startup/shtudown function to runtime PM handlers.

Changes since v2: (after Viorel's comments)
	- no need to check for is_slave_mode when enabling/disabling the clocks
	because sai->mclk_streams is only set when SAI is in master mode.

Changes since v1: (after Nicolin's comments)
	- added patch 1
	- added fsl_sai_remove in order to call pm_runtime_disable
	- only disable/enable mclk when SAI in master mode.

Daniel Baluta (2):
  ASoC: fsl_sai: Update is_slave_mode with correct value
  ASoC: fsl_sai: Add support for runtime pm

Shengjiu Wang (1):
  ASoC: fsl_sai: Move clock operation to PM runtime

 sound/soc/fsl/fsl_sai.c | 78 +++++++++++++++++++++++++++++++++--------
 1 file changed, 63 insertions(+), 15 deletions(-)

-- 
2.17.1


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

* [PATCH v3 1/3] ASoC: fsl_sai: Update is_slave_mode with correct value
  2019-04-22 19:02 [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Daniel Baluta
@ 2019-04-22 19:02 ` Daniel Baluta
  2019-04-22 19:02 ` [PATCH v3 2/3] ASoC: fsl_sai: Add support for runtime pm Daniel Baluta
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Daniel Baluta @ 2019-04-22 19:02 UTC (permalink / raw)
  To: broonie
  Cc: S.j. Wang, lgirdwood, timur, Xiubo.Lee, festevam, perex, tiwai,
	alsa-devel, linuxppc-dev, linux-kernel, dl-linux-imx,
	Daniel Baluta

is_slave_mode defaults to false because sai structure
that contains it is kzalloc'ed.

Anyhow, if we decide to set the following configuration
SAI slave -> SAI master, is_slave_mode will remain set on true
altough SAI being master it should be set to false.

Fix this by updating is_slave_mode for each call of
fsl_sai_set_dai_fmt.

Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index b563004fb89f..d9df98975cf8 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -268,12 +268,14 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
 	case SND_SOC_DAIFMT_CBS_CFS:
 		val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
 		val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
+		sai->is_slave_mode = false;
 		break;
 	case SND_SOC_DAIFMT_CBM_CFM:
 		sai->is_slave_mode = true;
 		break;
 	case SND_SOC_DAIFMT_CBS_CFM:
 		val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
+		sai->is_slave_mode = false;
 		break;
 	case SND_SOC_DAIFMT_CBM_CFS:
 		val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
-- 
2.17.1


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

* [PATCH v3 2/3] ASoC: fsl_sai: Add support for runtime pm
  2019-04-22 19:02 [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Daniel Baluta
  2019-04-22 19:02 ` [PATCH v3 1/3] ASoC: fsl_sai: Update is_slave_mode with correct value Daniel Baluta
@ 2019-04-22 19:02 ` Daniel Baluta
  2019-04-22 19:02 ` [PATCH v3 3/3] ASoC: fsl_sai: Move clock operation to PM runtime Daniel Baluta
  2019-04-23  7:20 ` [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Viorel Suman
  3 siblings, 0 replies; 6+ messages in thread
From: Daniel Baluta @ 2019-04-22 19:02 UTC (permalink / raw)
  To: broonie
  Cc: S.j. Wang, lgirdwood, timur, Xiubo.Lee, festevam, perex, tiwai,
	alsa-devel, linuxppc-dev, linux-kernel, dl-linux-imx,
	Daniel Baluta

Basically the same actions as for system PM, so make use
of pm_runtime_force_suspend/pm_runtime_force_resume.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
---
 sound/soc/fsl/fsl_sai.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d9df98975cf8..8623b7f882b9 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -9,6 +9,7 @@
 #include <linux/dmaengine.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
+#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/time.h>
@@ -900,6 +901,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, sai);
 
+	pm_runtime_enable(&pdev->dev);
+
 	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
 			&fsl_sai_dai, 1);
 	if (ret)
@@ -911,6 +914,11 @@ static int fsl_sai_probe(struct platform_device *pdev)
 		return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
 }
 
+static int fsl_sai_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+}
+
 static const struct of_device_id fsl_sai_ids[] = {
 	{ .compatible = "fsl,vf610-sai", },
 	{ .compatible = "fsl,imx6sx-sai", },
@@ -919,8 +927,8 @@ static const struct of_device_id fsl_sai_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, fsl_sai_ids);
 
-#ifdef CONFIG_PM_SLEEP
-static int fsl_sai_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static int fsl_sai_runtime_suspend(struct device *dev)
 {
 	struct fsl_sai *sai = dev_get_drvdata(dev);
 
@@ -930,7 +938,7 @@ static int fsl_sai_suspend(struct device *dev)
 	return 0;
 }
 
-static int fsl_sai_resume(struct device *dev)
+static int fsl_sai_runtime_resume(struct device *dev)
 {
 	struct fsl_sai *sai = dev_get_drvdata(dev);
 
@@ -942,14 +950,18 @@ static int fsl_sai_resume(struct device *dev)
 	regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
 	return regcache_sync(sai->regmap);
 }
-#endif /* CONFIG_PM_SLEEP */
+#endif /* CONFIG_PM */
 
 static const struct dev_pm_ops fsl_sai_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(fsl_sai_suspend, fsl_sai_resume)
+	SET_RUNTIME_PM_OPS(fsl_sai_runtime_suspend,
+			   fsl_sai_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
 };
 
 static struct platform_driver fsl_sai_driver = {
 	.probe = fsl_sai_probe,
+	.remove = fsl_sai_remove,
 	.driver = {
 		.name = "fsl-sai",
 		.pm = &fsl_sai_pm_ops,
-- 
2.17.1


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

* [PATCH v3 3/3] ASoC: fsl_sai: Move clock operation to PM runtime
  2019-04-22 19:02 [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Daniel Baluta
  2019-04-22 19:02 ` [PATCH v3 1/3] ASoC: fsl_sai: Update is_slave_mode with correct value Daniel Baluta
  2019-04-22 19:02 ` [PATCH v3 2/3] ASoC: fsl_sai: Add support for runtime pm Daniel Baluta
@ 2019-04-22 19:02 ` Daniel Baluta
  2019-04-26 12:11   ` Daniel Baluta
  2019-04-23  7:20 ` [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Viorel Suman
  3 siblings, 1 reply; 6+ messages in thread
From: Daniel Baluta @ 2019-04-22 19:02 UTC (permalink / raw)
  To: broonie
  Cc: S.j. Wang, lgirdwood, timur, Xiubo.Lee, festevam, perex, tiwai,
	alsa-devel, linuxppc-dev, linux-kernel, dl-linux-imx,
	Daniel Baluta

From: Shengjiu Wang <shengjiu.wang@nxp.com>

Turn off/on clocks when device enters suspend/resume. This
can help saving power.

As a further optimization, we turn off/on mclk only when SAI
is in master mode because otherwise mclk is externally provided.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
---
 sound/soc/fsl/fsl_sai.c | 54 +++++++++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 8623b7f882b9..7fd1a81ec1aa 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -596,15 +596,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
 {
 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-	struct device *dev = &sai->pdev->dev;
 	int ret;
 
-	ret = clk_prepare_enable(sai->bus_clk);
-	if (ret) {
-		dev_err(dev, "failed to enable bus clock: %d\n", ret);
-		return ret;
-	}
-
 	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
 			   FSL_SAI_CR3_TRCE);
 
@@ -621,8 +614,6 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
 	regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
-
-	clk_disable_unprepare(sai->bus_clk);
 }
 
 static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
@@ -932,6 +923,14 @@ static int fsl_sai_runtime_suspend(struct device *dev)
 {
 	struct fsl_sai *sai = dev_get_drvdata(dev);
 
+	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
+		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
+
+	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
+		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
+
+	clk_disable_unprepare(sai->bus_clk);
+
 	regcache_cache_only(sai->regmap, true);
 	regcache_mark_dirty(sai->regmap);
 
@@ -941,6 +940,25 @@ static int fsl_sai_runtime_suspend(struct device *dev)
 static int fsl_sai_runtime_resume(struct device *dev)
 {
 	struct fsl_sai *sai = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(sai->bus_clk);
+	if (ret) {
+		dev_err(dev, "failed to enable bus clock: %d\n", ret);
+		return ret;
+	}
+
+	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
+		ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
+		if (ret)
+			goto disable_bus_clk;
+	}
+
+	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
+		ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
+		if (ret)
+			goto disable_tx_clk;
+	}
 
 	regcache_cache_only(sai->regmap, false);
 	regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
@@ -948,7 +966,23 @@ static int fsl_sai_runtime_resume(struct device *dev)
 	usleep_range(1000, 2000);
 	regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
 	regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
-	return regcache_sync(sai->regmap);
+
+	ret = regcache_sync(sai->regmap);
+	if (ret)
+		goto disable_rx_clk;
+
+	return 0;
+
+disable_rx_clk:
+	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
+		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
+disable_tx_clk:
+	if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
+		clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
+disable_bus_clk:
+	clk_disable_unprepare(sai->bus_clk);
+
+	return ret;
 }
 #endif /* CONFIG_PM */
 
-- 
2.17.1


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

* Re: [PATCH v3 0/3] Add runtime PM for SAI digital audio interface
  2019-04-22 19:02 [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Daniel Baluta
                   ` (2 preceding siblings ...)
  2019-04-22 19:02 ` [PATCH v3 3/3] ASoC: fsl_sai: Move clock operation to PM runtime Daniel Baluta
@ 2019-04-23  7:20 ` Viorel Suman
  3 siblings, 0 replies; 6+ messages in thread
From: Viorel Suman @ 2019-04-23  7:20 UTC (permalink / raw)
  To: Daniel Baluta, broonie
  Cc: dl-linux-imx, linux-kernel, linuxppc-dev, timur, Xiubo.Lee,
	festevam, tiwai, lgirdwood, S.j. Wang, perex, alsa-devel

For this series:

Reviewed-by: Viorel Suman <viorel.suman@nxp.com>

On Lu, 2019-04-22 at 19:02 +0000, Daniel Baluta wrote:
> First patch fixes a bug by correctly setting is_slave_mode, then
> second patch adds support for runtime PM and finally 3rd patch moves
> clock handling from startup/shtudown function to runtime PM handlers.
> 
> Changes since v2: (after Viorel's comments)
> 	- no need to check for is_slave_mode when enabling/disabling the clocks
> 	because sai->mclk_streams is only set when SAI is in master mode.
> 
> Changes since v1: (after Nicolin's comments)
> 	- added patch 1
> 	- added fsl_sai_remove in order to call pm_runtime_disable
> 	- only disable/enable mclk when SAI in master mode.
> 
> Daniel Baluta (2):
>   ASoC: fsl_sai: Update is_slave_mode with correct value
>   ASoC: fsl_sai: Add support for runtime pm
> 
> Shengjiu Wang (1):
>   ASoC: fsl_sai: Move clock operation to PM runtime
> 
>  sound/soc/fsl/fsl_sai.c | 78 +++++++++++++++++++++++++++++++++--------
>  1 file changed, 63 insertions(+), 15 deletions(-)
> 
> -- 
> 2.17.1
> 

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

* Re: [PATCH v3 3/3] ASoC: fsl_sai: Move clock operation to PM runtime
  2019-04-22 19:02 ` [PATCH v3 3/3] ASoC: fsl_sai: Move clock operation to PM runtime Daniel Baluta
@ 2019-04-26 12:11   ` Daniel Baluta
  0 siblings, 0 replies; 6+ messages in thread
From: Daniel Baluta @ 2019-04-26 12:11 UTC (permalink / raw)
  To: Daniel Baluta
  Cc: broonie, S.j. Wang, lgirdwood, timur, Xiubo.Lee, festevam, perex,
	tiwai, alsa-devel, linuxppc-dev, linux-kernel, dl-linux-imx

Hi Mark,

This is the only patch in the series that wasn't applied.

On Mon, Apr 22, 2019 at 10:03 PM Daniel Baluta <daniel.baluta@nxp.com> wrote:
>
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> Turn off/on clocks when device enters suspend/resume. This
> can help saving power.
>
> As a further optimization, we turn off/on mclk only when SAI
> is in master mode because otherwise mclk is externally provided.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
> ---
>  sound/soc/fsl/fsl_sai.c | 54 +++++++++++++++++++++++++++++++++--------
>  1 file changed, 44 insertions(+), 10 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index 8623b7f882b9..7fd1a81ec1aa 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -596,15 +596,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
>  {
>         struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
>         bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
> -       struct device *dev = &sai->pdev->dev;
>         int ret;
>
> -       ret = clk_prepare_enable(sai->bus_clk);
> -       if (ret) {
> -               dev_err(dev, "failed to enable bus clock: %d\n", ret);
> -               return ret;
> -       }
> -
>         regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
>                            FSL_SAI_CR3_TRCE);
>
> @@ -621,8 +614,6 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
>         bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
>
>         regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
> -
> -       clk_disable_unprepare(sai->bus_clk);
>  }
>
>  static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
> @@ -932,6 +923,14 @@ static int fsl_sai_runtime_suspend(struct device *dev)
>  {
>         struct fsl_sai *sai = dev_get_drvdata(dev);
>
> +       if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
> +               clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
> +
> +       if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
> +               clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
> +
> +       clk_disable_unprepare(sai->bus_clk);
> +
>         regcache_cache_only(sai->regmap, true);
>         regcache_mark_dirty(sai->regmap);
>
> @@ -941,6 +940,25 @@ static int fsl_sai_runtime_suspend(struct device *dev)
>  static int fsl_sai_runtime_resume(struct device *dev)
>  {
>         struct fsl_sai *sai = dev_get_drvdata(dev);
> +       int ret;
> +
> +       ret = clk_prepare_enable(sai->bus_clk);
> +       if (ret) {
> +               dev_err(dev, "failed to enable bus clock: %d\n", ret);
> +               return ret;
> +       }
> +
> +       if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
> +               ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
> +               if (ret)
> +                       goto disable_bus_clk;
> +       }
> +
> +       if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
> +               ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
> +               if (ret)
> +                       goto disable_tx_clk;
> +       }
>
>         regcache_cache_only(sai->regmap, false);
>         regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
> @@ -948,7 +966,23 @@ static int fsl_sai_runtime_resume(struct device *dev)
>         usleep_range(1000, 2000);
>         regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
>         regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
> -       return regcache_sync(sai->regmap);
> +
> +       ret = regcache_sync(sai->regmap);
> +       if (ret)
> +               goto disable_rx_clk;
> +
> +       return 0;
> +
> +disable_rx_clk:
> +       if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
> +               clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
> +disable_tx_clk:
> +       if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
> +               clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
> +disable_bus_clk:
> +       clk_disable_unprepare(sai->bus_clk);
> +
> +       return ret;
>  }
>  #endif /* CONFIG_PM */
>
> --
> 2.17.1
>

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

end of thread, other threads:[~2019-04-26 12:11 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-22 19:02 [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Daniel Baluta
2019-04-22 19:02 ` [PATCH v3 1/3] ASoC: fsl_sai: Update is_slave_mode with correct value Daniel Baluta
2019-04-22 19:02 ` [PATCH v3 2/3] ASoC: fsl_sai: Add support for runtime pm Daniel Baluta
2019-04-22 19:02 ` [PATCH v3 3/3] ASoC: fsl_sai: Move clock operation to PM runtime Daniel Baluta
2019-04-26 12:11   ` Daniel Baluta
2019-04-23  7:20 ` [PATCH v3 0/3] Add runtime PM for SAI digital audio interface Viorel Suman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).