ASoC: SOF: Intel: LNL: enable DMIC/SSP offload in probe/resume

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>
This commit is contained in:
Pierre-Louis Bossart 2023-08-07 16:09:47 -05:00 committed by Mark Brown
parent c22d532797
commit e78576c4aa
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
1 changed files with 56 additions and 0 deletions

View 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);