ASoC: SOF: PM: Add support for DSP D0i3 state when entering S0ix

When system is entering into S0ix, the PCI device may transition to the
D0i3 substate instead of D3. In D0i3, some always-on functionality can
be enabled, such as acoustic event detection, voice activity detection
or hotwording. When an event is detected, the DSP firmware can wake-up
the device for a transition to D0 with an interrupt.

Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20191025224122.7718-26-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Keyon Jie 2019-10-25 17:41:21 -05:00 committed by Mark Brown
parent 5655ce660a
commit c470fc3f61
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -430,12 +430,58 @@ EXPORT_SYMBOL(snd_sof_set_d0_substate);
int snd_sof_resume(struct device *dev)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
int ret;
if (sdev->s0_suspend) {
/* resume from D0I3 */
dev_dbg(sdev->dev, "DSP will exit from D0i3...\n");
ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I0);
if (ret == -ENOTSUPP) {
/* fallback to resume from D3 */
dev_dbg(sdev->dev, "D0i3 not supported, fall back to resume from D3...\n");
goto d3_resume;
} else if (ret < 0) {
dev_err(sdev->dev, "error: failed to exit from D0I3 %d\n",
ret);
return ret;
}
/* platform-specific resume from D0i3 */
return snd_sof_dsp_resume(sdev);
}
d3_resume:
/* resume from D3 */
return sof_resume(dev, false);
}
EXPORT_SYMBOL(snd_sof_resume);
int snd_sof_suspend(struct device *dev)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
int ret;
if (sdev->s0_suspend) {
/* suspend to D0i3 */
dev_dbg(sdev->dev, "DSP is trying to enter D0i3...\n");
ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I3);
if (ret == -ENOTSUPP) {
/* fallback to D3 suspend */
dev_dbg(sdev->dev, "D0i3 not supported, fall back to D3...\n");
goto d3_suspend;
} else if (ret < 0) {
dev_err(sdev->dev, "error: failed to enter D0I3, %d\n",
ret);
return ret;
}
/* platform-specific suspend to D0i3 */
return snd_sof_dsp_suspend(sdev);
}
d3_suspend:
/* suspend to D3 */
return sof_suspend(dev, false);
}
EXPORT_SYMBOL(snd_sof_suspend);