From f5762411c5a60a49bec2380d55aec95debe3de78 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Sat, 2 Nov 2019 01:13:59 +0800 Subject: [PATCH 1/4] ASoC: SOF: PM: add check before setting d0_substate Add check before seeting d0_substate and return success if Audio DSP is already in the target substate. Signed-off-by: Keyon Jie --- sound/soc/sof/pm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 560a937e048420..717251432ee93b 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -416,6 +416,9 @@ int snd_sof_set_d0_substate(struct snd_sof_dev *sdev, { int ret; + if (sdev->d0_substate == d0_substate) + return 0; + /* do platform specific set_state */ ret = snd_sof_dsp_set_power_state(sdev, d0_substate); if (ret < 0) From 537a5d7b8e135aebbebf91556ded6dde80842242 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Fri, 8 Nov 2019 08:26:28 +0800 Subject: [PATCH 2/4] ASoC: SOF: add helper to check if we should enter d0i3 suspend Add helper to check if the DSP should be put in D0i3. This function returns true if a stream has ignored the SUSPEND trigger to keep the pipelines running in the DSP. Signed-off-by: Keyon Jie --- sound/soc/sof/core.c | 13 +++++++++++++ sound/soc/sof/sof-priv.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 8661c2cca76b9a..805918d3bcc09d 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -132,6 +132,19 @@ struct snd_sof_dai *snd_sof_find_dai(struct snd_sof_dev *sdev, return NULL; } +bool snd_sof_dsp_d0i3_on_suspend(struct snd_sof_dev *sdev) +{ + struct snd_sof_pcm *spcm; + + list_for_each_entry(spcm, &sdev->pcm_list, list) { + if (spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].suspend_ignored || + spcm->stream[SNDRV_PCM_STREAM_CAPTURE].suspend_ignored) + return true; + } + + return false; +} + /* * FW Panic/fault handling. */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 6408ac88a3e582..c7c2c70ee4d04d 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -553,6 +553,8 @@ struct snd_sof_pcm *snd_sof_find_spcm_dai(struct snd_sof_dev *sdev, return NULL; } +bool snd_sof_dsp_d0i3_on_suspend(struct snd_sof_dev *sdev); + struct snd_sof_pcm *snd_sof_find_spcm_name(struct snd_sof_dev *sdev, const char *name); struct snd_sof_pcm *snd_sof_find_spcm_comp(struct snd_sof_dev *sdev, From 8765183e4de879285a53ea5154411f9a87f09b5b Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Fri, 1 Nov 2019 05:43:46 +0800 Subject: [PATCH 3/4] ASoC: SOF: PM: only suspend to D0I3 when needed We should suspend audio to D3 by default, for the sake of power saving, change the condition of D0I3 suspending here to that when there is stream with suspend_ignored specified. Signed-off-by: Keyon Jie --- sound/soc/sof/pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 717251432ee93b..1436cb201fa07b 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -436,7 +436,7 @@ int snd_sof_resume(struct device *dev) struct snd_sof_dev *sdev = dev_get_drvdata(dev); int ret; - if (sdev->s0_suspend) { + if (snd_sof_dsp_d0i3_on_suspend(sdev)) { /* resume from D0I3 */ dev_dbg(sdev->dev, "DSP will exit from D0i3...\n"); ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I0); @@ -465,7 +465,7 @@ int snd_sof_suspend(struct device *dev) struct snd_sof_dev *sdev = dev_get_drvdata(dev); int ret; - if (sdev->s0_suspend) { + if (snd_sof_dsp_d0i3_on_suspend(sdev)) { /* suspend to D0i3 */ dev_dbg(sdev->dev, "DSP is trying to enter D0i3...\n"); ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I3); From d7ea7468e2eb4019080740af8b944d11ebcd8f31 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Tue, 5 Nov 2019 06:44:30 +0800 Subject: [PATCH 4/4] ASoC: SOF: PM: add state machine to comments Add Audio DSP state machine with comments, be noticed that the 'D0<-->runtime D0I3' part is not implemented yet. Signed-off-by: Keyon Jie --- sound/soc/sof/pm.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 1436cb201fa07b..0fd5567237a8d5 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -431,6 +431,38 @@ int snd_sof_set_d0_substate(struct snd_sof_dev *sdev, } EXPORT_SYMBOL(snd_sof_set_d0_substate); +/* + * Audio DSP states may transform as below:- + * + * D0I3 compatible stream + * Runtime +---------------------+ opened only, timeout + * suspend | +--------------------+ + * +------------+ D0(active) | | + * | | <---------------+ | + * | +--------> | | | + * | |Runtime +--^--+---------^--+--+ The last | | + * | |resume | | | | opened D0I3 | | + * | | | | | | compatible | | + * | | resume| | | | stream closed | | + * | | from | | D3 | | | | + * | | D3 | |suspend | | d0i3 | | + * | | | | | |suspend | | + * | | | | | | | | + * | | | | | | | | + * +-v---+-----------+--v-------+ | | +------+----v----+ + * | | | +-----------> | + * | D3 (suspended) | | | D0I3 +-----+ + * | | +--------------+ | | + * | | resume from | | | + * +-------------------^--------+ d0i3 suspend +----------------+ | + * | | + * | D3 suspend | + * +------------------------------------------------+ + * + * d0i3_suspend = s0_suspend && D0I3 stream opened, + * D3 suspend = !d0i3_suspend, + */ + int snd_sof_resume(struct device *dev) { struct snd_sof_dev *sdev = dev_get_drvdata(dev);