Unverified Commit 28d40e7a authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown
Browse files

ASoC: SOF: Add support for DSPless mode



Via the SOF_DBG_DSPLESS_MODE sof_debug flag the SOF stack can be asked to
not use the DSP for audio.

The core's support for DSPless mode is only going to be enabled if the
platform reports that it can be used without DSP.

Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarRander Wang <rander.wang@intel.com>
Link: https://lore.kernel.org/r/20230404092115.27949-4-peter.ujfalusi@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 59611370
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -208,6 +208,11 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
	/* set up platform component driver */
	snd_sof_new_platform_drv(sdev);

	if (sdev->dspless_mode_selected) {
		sof_set_fw_state(sdev, SOF_DSPLESS_MODE);
		goto skip_dsp_init;
	}

	/* register any debug/trace capabilities */
	ret = snd_sof_dbg_init(sdev);
	if (ret < 0) {
@@ -266,6 +271,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
		dev_dbg(sdev->dev, "SOF firmware trace disabled\n");
	}

skip_dsp_init:
	/* hereafter all FW boot flows are for PM reasons */
	sdev->first_boot = false;

@@ -387,12 +393,18 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
		return ret;

	/* check all mandatory ops */
	if (!sof_ops(sdev) || !sof_ops(sdev)->probe || !sof_ops(sdev)->run ||
	    !sof_ops(sdev)->block_read || !sof_ops(sdev)->block_write ||
	    !sof_ops(sdev)->send_msg || !sof_ops(sdev)->load_firmware ||
	    !sof_ops(sdev)->ipc_msg_data) {
	if (!sof_ops(sdev) || !sof_ops(sdev)->probe) {
		sof_ops_free(sdev);
		dev_err(dev, "missing mandatory ops\n");
		return -EINVAL;
	}

	if (!sdev->dspless_mode_selected &&
	    (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read ||
	     !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg ||
	     !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) {
		sof_ops_free(sdev);
		dev_err(dev, "error: missing mandatory ops\n");
		dev_err(dev, "missing mandatory DSP ops\n");
		return -EINVAL;
	}

+1 −0
Original line number Diff line number Diff line
@@ -370,6 +370,7 @@ static const struct soc_fw_state_info {
	const char *name;
} fw_state_dbg[] = {
	{SOF_FW_BOOT_NOT_STARTED, "SOF_FW_BOOT_NOT_STARTED"},
	{SOF_DSPLESS_MODE, "SOF_DSPLESS_MODE"},
	{SOF_FW_BOOT_PREPARE, "SOF_FW_BOOT_PREPARE"},
	{SOF_FW_BOOT_IN_PROGRESS, "SOF_FW_BOOT_IN_PROGRESS"},
	{SOF_FW_BOOT_FAILED, "SOF_FW_BOOT_FAILED"},
+12 −1
Original line number Diff line number Diff line
@@ -330,6 +330,11 @@ static int sof_pcm_trigger(struct snd_soc_component *component,
			spcm->stream[substream->stream].suspend_ignored = true;
			return 0;
		}

		/* On suspend the DMA must be stopped in DSPless mode */
		if (sdev->dspless_mode_selected)
			reset_hw_params = true;

		fallthrough;
	case SNDRV_PCM_TRIGGER_STOP:
		ipc_first = true;
@@ -705,7 +710,6 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev)

	pd->pcm_construct = sof_pcm_new;
	pd->ignore_machine = drv_name;
	pd->be_hw_params_fixup = sof_pcm_dai_link_fixup;
	pd->be_pcm_base = SOF_BE_PCM_BASE;
	pd->use_dai_pcm_id = true;
	pd->topology_name_prefix = "sof";
@@ -714,4 +718,11 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev)
	pd->module_get_upon_open = 1;

	pd->legacy_dai_naming = 1;

	/*
	 * The fixup is only needed when the DSP is in use as with the DSPless
	 * mode we are directly using the audio interface
	 */
	if (!sdev->dspless_mode_selected)
		pd->be_hw_params_fixup = sof_pcm_dai_link_fixup;
}
+5 −0
Original line number Diff line number Diff line
@@ -103,6 +103,11 @@ static int sof_resume(struct device *dev, bool runtime_resume)
		return ret;
	}

	if (sdev->dspless_mode_selected) {
		sof_set_fw_state(sdev, SOF_DSPLESS_MODE);
		return 0;
	}

	/*
	 * Nothing further to be done for platforms that support the low power
	 * D0 substate. Resume trace and return when resuming from
+1 −1
Original line number Diff line number Diff line
@@ -688,7 +688,7 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm,
		struct snd_sof_widget *pipe_widget;
		struct snd_sof_pipeline *spipe;

		if (!swidget)
		if (!swidget || sdev->dspless_mode_selected)
			continue;

		spipe = swidget->spipe;
Loading