* [PATCH v2 1/3] ASoC: hdac_hdmi: report codec link up/down status to bus
2019-06-18 10:18 [PATCH v2 0/3] ASoC: SOF: fix suspend ordering with runtime idle Kai Vehmanen
@ 2019-06-18 10:18 ` Kai Vehmanen
2019-06-18 10:18 ` [PATCH v2 2/3] ASoC: SOF: add runtime idle callback Kai Vehmanen
2019-06-18 10:18 ` [PATCH v2 3/3] ASoC: SOF: Intel: implement runtime idle for CNL/APL Kai Vehmanen
2 siblings, 0 replies; 4+ messages in thread
From: Kai Vehmanen @ 2019-06-18 10:18 UTC (permalink / raw)
To: alsa-devel, broonie; +Cc: tiwai, libin.yang, pierre-louis.bossart, kai.vehmanen
Report codec power status to the HDA codec bus from runtime pm
suspend and resume callbacks. This is required to implement
runtime idle logic that relies on 'codec_powered' field of hdac_bus
to be maintained for all codecs.
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
---
sound/soc/codecs/hdac_hdmi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 660e0587f3999..01ab7aed315cb 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -2090,6 +2090,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
return -EIO;
}
+ snd_hdac_codec_link_down(hdev);
snd_hdac_ext_bus_link_put(bus, hlink);
snd_hdac_display_power(bus, hdev->addr, false);
@@ -2116,6 +2117,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
}
snd_hdac_ext_bus_link_get(bus, hlink);
+ snd_hdac_codec_link_up(hdev);
snd_hdac_display_power(bus, hdev->addr, true);
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/3] ASoC: SOF: add runtime idle callback
2019-06-18 10:18 [PATCH v2 0/3] ASoC: SOF: fix suspend ordering with runtime idle Kai Vehmanen
2019-06-18 10:18 ` [PATCH v2 1/3] ASoC: hdac_hdmi: report codec link up/down status to bus Kai Vehmanen
@ 2019-06-18 10:18 ` Kai Vehmanen
2019-06-18 10:18 ` [PATCH v2 3/3] ASoC: SOF: Intel: implement runtime idle for CNL/APL Kai Vehmanen
2 siblings, 0 replies; 4+ messages in thread
From: Kai Vehmanen @ 2019-06-18 10:18 UTC (permalink / raw)
To: alsa-devel, broonie; +Cc: tiwai, libin.yang, pierre-louis.bossart, kai.vehmanen
Add ability to implement a SOF device level runtime idle callback.
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
---
sound/soc/sof/intel/hda.h | 1 +
sound/soc/sof/ops.h | 8 ++++++++
sound/soc/sof/pm.c | 8 ++++++++
sound/soc/sof/sof-acpi-dev.c | 2 +-
sound/soc/sof/sof-pci-dev.c | 2 +-
sound/soc/sof/sof-priv.h | 2 ++
6 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 73d7cc08afc22..d9c17146200b3 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -457,6 +457,7 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state);
int hda_dsp_resume(struct snd_sof_dev *sdev);
int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state);
int hda_dsp_runtime_resume(struct snd_sof_dev *sdev);
+int hda_dsp_runtime_idle(struct snd_sof_dev *sdev);
int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev);
void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags);
void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags);
diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h
index 45a3d10911634..b9bdf45889da1 100644
--- a/sound/soc/sof/ops.h
+++ b/sound/soc/sof/ops.h
@@ -134,6 +134,14 @@ static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev,
return 0;
}
+static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev)
+{
+ if (sof_ops(sdev)->runtime_idle)
+ return sof_ops(sdev)->runtime_idle(sdev);
+
+ return 0;
+}
+
static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev)
{
if (sof_ops(sdev)->set_hw_params_upon_resume)
diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
index 8eeb3a1029f24..278abfd10490d 100644
--- a/sound/soc/sof/pm.c
+++ b/sound/soc/sof/pm.c
@@ -394,6 +394,14 @@ int snd_sof_runtime_suspend(struct device *dev)
}
EXPORT_SYMBOL(snd_sof_runtime_suspend);
+int snd_sof_runtime_idle(struct device *dev)
+{
+ struct snd_sof_dev *sdev = dev_get_drvdata(dev);
+
+ return snd_sof_dsp_runtime_idle(sdev);
+}
+EXPORT_SYMBOL(snd_sof_runtime_idle);
+
int snd_sof_runtime_resume(struct device *dev)
{
return sof_resume(dev, true);
diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c
index c8dafb1ac54e2..ea7b8b8954128 100644
--- a/sound/soc/sof/sof-acpi-dev.c
+++ b/sound/soc/sof/sof-acpi-dev.c
@@ -116,7 +116,7 @@ static const struct sof_dev_desc sof_acpi_cherrytrail_desc = {
static const struct dev_pm_ops sof_acpi_pm = {
SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume)
SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume,
- NULL)
+ snd_sof_runtime_idle)
};
static void sof_acpi_probe_complete(struct device *dev)
diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
index e2b19782f01ac..65d1bac4c6b8b 100644
--- a/sound/soc/sof/sof-pci-dev.c
+++ b/sound/soc/sof/sof-pci-dev.c
@@ -206,7 +206,7 @@ static const struct sof_dev_desc kbl_desc = {
static const struct dev_pm_ops sof_pci_pm = {
SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume)
SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume,
- NULL)
+ snd_sof_runtime_idle)
};
static void sof_pci_probe_complete(struct device *dev)
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 58621db4fd31a..b8c0b2a226845 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -176,6 +176,7 @@ struct snd_sof_dsp_ops {
int (*runtime_suspend)(struct snd_sof_dev *sof_dev,
int state); /* optional */
int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */
+ int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */
int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */
/* DSP clocking */
@@ -446,6 +447,7 @@ int snd_sof_device_remove(struct device *dev);
int snd_sof_runtime_suspend(struct device *dev);
int snd_sof_runtime_resume(struct device *dev);
+int snd_sof_runtime_idle(struct device *dev);
int snd_sof_resume(struct device *dev);
int snd_sof_suspend(struct device *dev);
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v2 3/3] ASoC: SOF: Intel: implement runtime idle for CNL/APL
2019-06-18 10:18 [PATCH v2 0/3] ASoC: SOF: fix suspend ordering with runtime idle Kai Vehmanen
2019-06-18 10:18 ` [PATCH v2 1/3] ASoC: hdac_hdmi: report codec link up/down status to bus Kai Vehmanen
2019-06-18 10:18 ` [PATCH v2 2/3] ASoC: SOF: add runtime idle callback Kai Vehmanen
@ 2019-06-18 10:18 ` Kai Vehmanen
2 siblings, 0 replies; 4+ messages in thread
From: Kai Vehmanen @ 2019-06-18 10:18 UTC (permalink / raw)
To: alsa-devel, broonie; +Cc: tiwai, libin.yang, pierre-louis.bossart, kai.vehmanen
Implement runtime idle for CNL/APL devices using similar runtime
PM idle logic as the Intel AZX HDA driver. If any HDA codecs are
powered when runtime suspend request comes, return -EBUSY. By doing
this, strict ordering is enforced between HDA codec and the HDA
controller.
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
---
sound/soc/sof/intel/apl.c | 1 +
sound/soc/sof/intel/cnl.c | 1 +
sound/soc/sof/intel/hda-dsp.c | 13 +++++++++++++
3 files changed, 15 insertions(+)
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index 43d1c9f31ec4c..fd2e26d797961 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -93,6 +93,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
.resume = hda_dsp_resume,
.runtime_suspend = hda_dsp_runtime_suspend,
.runtime_resume = hda_dsp_runtime_resume,
+ .runtime_idle = hda_dsp_runtime_idle,
.set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume,
};
EXPORT_SYMBOL(sof_apl_ops);
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 3840f81767fab..f2b392998f20d 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -251,6 +251,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
.resume = hda_dsp_resume,
.runtime_suspend = hda_dsp_runtime_suspend,
.runtime_resume = hda_dsp_runtime_resume,
+ .runtime_idle = hda_dsp_runtime_idle,
.set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume,
};
EXPORT_SYMBOL(sof_cnl_ops);
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index f2c5a12db930a..91de4785b6a3e 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -418,6 +418,19 @@ int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
return hda_resume(sdev);
}
+int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
+{
+ struct hdac_bus *hbus = sof_to_bus(sdev);
+
+ if (hbus->codec_powered) {
+ dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n",
+ (unsigned int)hbus->codec_powered);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state)
{
/* stop hda controller and power dsp off */
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread