diff mbox series

[08/20] ASoC: SOF: Intel: LNL: enable DMIC/SSP offload in probe/resume

Message ID 20230807210959.506849-9-pierre-louis.bossart@linux.intel.com
State Accepted
Commit e78576c4aa0d5b7185e1f5188578d9bfb2d43d4b
Headers show
Series ASoC: SOF: Intel: add LunarLake support | expand

Commit Message

Pierre-Louis Bossart Aug. 7, 2023, 9:09 p.m. UTC
In the LunarLake hardware, the default IP ownership changed to the
host driver, instead of the firmware in previous generation.

In the absence of any capability negotiation, we need to assume a
fixed partitioning between host driver and firmware. The OFLEN bit
needs to be set as early as possible for resources handled by the
firmware, since we can't control when the firmware might try to access
the resources.

For now DMIC and SSP are handled by the DSP firmware. SoundWire is a
separate case, the OFLEN bit can be set when starting-up and resuming
the aux device for each link.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
---
 sound/soc/sof/intel/lnl.c | 56 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
diff mbox series

Patch

diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c
index 65a78d9511e9..3d919b0b6891 100644
--- a/sound/soc/sof/intel/lnl.c
+++ b/sound/soc/sof/intel/lnl.c
@@ -29,6 +29,55 @@  static const struct snd_sof_debugfs_map lnl_dsp_debugfs[] = {
 	{"dsp", HDA_DSP_BAR,  0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
 };
 
+/* this helps allows the DSP to setup DMIC/SSP */
+static int hdac_bus_offload_dmic_ssp(struct hdac_bus *bus)
+{
+	int ret;
+
+	ret = hdac_bus_eml_enable_offload(bus, true,  AZX_REG_ML_LEPTR_ID_INTEL_SSP, true);
+	if (ret < 0)
+		return ret;
+
+	ret = hdac_bus_eml_enable_offload(bus, true,  AZX_REG_ML_LEPTR_ID_INTEL_DMIC, true);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int lnl_hda_dsp_probe(struct snd_sof_dev *sdev)
+{
+	int ret;
+
+	ret = hda_dsp_probe(sdev);
+	if (ret < 0)
+		return ret;
+
+	return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev));
+}
+
+static int lnl_hda_dsp_resume(struct snd_sof_dev *sdev)
+{
+	int ret;
+
+	ret = hda_dsp_resume(sdev);
+	if (ret < 0)
+		return ret;
+
+	return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev));
+}
+
+static int lnl_hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
+{
+	int ret;
+
+	ret = hda_dsp_runtime_resume(sdev);
+	if (ret < 0)
+		return ret;
+
+	return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev));
+}
+
 int sof_lnl_ops_init(struct snd_sof_dev *sdev)
 {
 	struct sof_ipc4_fw_data *ipc4_data;
@@ -36,6 +85,9 @@  int sof_lnl_ops_init(struct snd_sof_dev *sdev)
 	/* common defaults */
 	memcpy(&sof_lnl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
 
+	/* probe */
+	sof_lnl_ops.probe = lnl_hda_dsp_probe;
+
 	/* shutdown */
 	sof_lnl_ops.shutdown = hda_dsp_shutdown;
 
@@ -63,6 +115,10 @@  int sof_lnl_ops_init(struct snd_sof_dev *sdev)
 	/* dsp core get/put */
 	/* TODO: add core_get and core_put */
 
+	/* PM */
+	sof_lnl_ops.resume			= lnl_hda_dsp_resume;
+	sof_lnl_ops.runtime_resume		= lnl_hda_dsp_runtime_resume;
+
 	sof_lnl_ops.get_stream_position = mtl_dsp_get_stream_hda_link_position;
 
 	sdev->private = devm_kzalloc(sdev->dev, sizeof(struct sof_ipc4_fw_data), GFP_KERNEL);