ASoC: SOF: Intel: LNL: enable DMIC/SSP offload in probe/resume
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Mon, 7 Aug 2023 21:09:47 +0000 (16:09 -0500)
committerMark Brown <broonie@kernel.org>
Mon, 7 Aug 2023 22:09:37 +0000 (23:09 +0100)
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>
Link: https://lore.kernel.org/r/20230807210959.506849-9-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/lnl.c

index 65a78d9..3d919b0 100644 (file)
@@ -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);