Unverified Commit 54f5bae0 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: SOF: IPC client infrastructure

Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>:

The Linux SOF implementation is historically monolithic in a sense that all
features accessible in the firmware can be used via the snd_sof_dev struct in
one way or another.

Support for features can not be added or removed runtime and with the current
way of things it is hard if not impossible to implement support for dynamic
feature support when based on the firmware manifest we can easily enable/access
independent modules with the SOF.

In order to be able to support such modularity this series introduces a small
framework within SOF for client support using the Auxiliary bus.

Client drivers can be removed runtime and later re-loaded if needed without
affecting the core's behaviour, but it is the core's and the platform's duty
to create the Auxiliary devices usable in the platform and via the firmware.

There is still a need for SOF manifest update to convey information about
features to really make the full dynamic client device creation.

The series will introduce the core SOF client support and converts the generic
ipc flood test, ipc message injector and the probes (Intel HDA only) to a client
driver.
parents a61faea1 3dc0d709
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -39,6 +39,14 @@ enum sof_fw_state {
	SOF_FW_CRASHED,
};

/* DSP power states */
enum sof_dsp_power_states {
	SOF_DSP_PM_D0,
	SOF_DSP_PM_D1,
	SOF_DSP_PM_D2,
	SOF_DSP_PM_D3,
};

/*
 * SOF Platform data.
 */
+26 −7
Original line number Diff line number Diff line
@@ -53,13 +53,21 @@ config SND_SOC_SOF_COMPRESS
	select SND_SOC_COMPRESS

config SND_SOC_SOF_DEBUG_PROBES
	bool "SOF enable data probing"
	tristate
	select SND_SOC_SOF_CLIENT
	select SND_SOC_COMPRESS
	help
	  This option enables the data probing feature that can be used to
	  gather data directly from specific points of the audio pipeline.
	  Say Y if you want to enable probes.
	  If unsure, select "N".
	  This option is not user-selectable but automagically handled by
	  'select' statements at a higher level.

config SND_SOC_SOF_CLIENT
	tristate
	select AUXILIARY_BUS
	help
	  This option is not user-selectable but automagically handled by
	  'select' statements at a higher level.

config SND_SOC_SOF_DEVELOPER_SUPPORT
	bool "SOF developer options support"
@@ -187,15 +195,26 @@ config SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE
	  If unsure, select "N".

config SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST
	bool "SOF enable IPC flood test"
	tristate "SOF enable IPC flood test"
	select SND_SOC_SOF_CLIENT
	help
	  This option enables the IPC flood test which can be used to flood
	  the DSP with test IPCs and gather stats about response times.
	  This option enables a separate client device for IPC flood test
	  which can be used to flood the DSP with test IPCs and gather stats
	  about response times.
	  Say Y if you want to enable IPC flood test.
	  If unsure, select "N".

config SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST_NUM
	int "Number of IPC flood test clients"
	range 1 32
	default 2
	depends on SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST
	help
	  Select the number of IPC flood test clients to be created.

config SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR
	bool "SOF enable IPC message injector"
	tristate "SOF enable IPC message injector"
	select SND_SOC_SOF_CLIENT
	help
	  This option enables the IPC message injector which can be used to send
	  crafted IPC messages to the DSP to test its robustness.
+13 −2
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)

snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
		control.o trace.o utils.o sof-audio.o stream-ipc.o
		control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o
snd-sof-$(CONFIG_SND_SOC_SOF_CLIENT) += sof-client.o

snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += compress.o

snd-sof-pci-objs := sof-pci-dev.o
snd-sof-acpi-objs := sof-acpi-dev.o
snd-sof-of-objs := sof-of-dev.o

snd-sof-ipc-flood-test-objs := sof-client-ipc-flood-test.o
snd-sof-ipc-msg-injector-objs := sof-client-ipc-msg-injector.o
snd-sof-probes-objs := sof-client-probes.o

snd-sof-nocodec-objs := nocodec.o

snd-sof-utils-objs := sof-utils.o

obj-$(CONFIG_SND_SOC_SOF) += snd-sof.o
obj-$(CONFIG_SND_SOC_SOF_NOCODEC) += snd-sof-nocodec.o

obj-$(CONFIG_SND_SOC_SOF) += snd-sof-utils.o

obj-$(CONFIG_SND_SOC_SOF_ACPI_DEV) += snd-sof-acpi.o
obj-$(CONFIG_SND_SOC_SOF_OF_DEV) += snd-sof-of.o
obj-$(CONFIG_SND_SOC_SOF_PCI_DEV) += snd-sof-pci.o

obj-$(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) += snd-sof-ipc-flood-test.o
obj-$(CONFIG_SND_SOC_SOF_DEBUG_IPC_MSG_INJECTOR) += snd-sof-ipc-msg-injector.o
obj-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += snd-sof-probes.o

obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/
obj-$(CONFIG_SND_SOC_SOF_IMX_TOPLEVEL) += imx/
obj-$(CONFIG_SND_SOC_SOF_AMD_TOPLEVEL) += amd/
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <sound/compress_driver.h>
#include "sof-audio.h"
#include "sof-priv.h"
#include "sof-utils.h"

static void sof_set_transferred_bytes(struct snd_compr_tstamp *tstamp,
				      u64 host_pos, u64 buffer_size)
+43 −7
Original line number Diff line number Diff line
@@ -14,9 +14,6 @@
#include <sound/sof.h>
#include "sof-priv.h"
#include "ops.h"
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
#include "sof-probes.h"
#endif

/* see SOF_DBG_ flags */
static int sof_core_debug =  IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE);
@@ -122,6 +119,27 @@ void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level,
}
EXPORT_SYMBOL(sof_print_oops_and_stack);

/* Helper to manage DSP state */
void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state)
{
	if (sdev->fw_state == new_state)
		return;

	dev_dbg(sdev->dev, "fw_state change: %d -> %d\n", sdev->fw_state, new_state);
	sdev->fw_state = new_state;

	switch (new_state) {
	case SOF_FW_BOOT_NOT_STARTED:
	case SOF_FW_BOOT_COMPLETE:
	case SOF_FW_CRASHED:
		sof_client_fw_state_dispatcher(sdev);
		fallthrough;
	default:
		break;
	}
}
EXPORT_SYMBOL(sof_set_fw_state);

/*
 *			FW Boot State Transition Diagram
 *
@@ -266,6 +284,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
		goto fw_trace_err;
	}

	ret = sof_register_clients(sdev);
	if (ret < 0) {
		dev_err(sdev->dev, "failed to register clients %d\n", ret);
		goto sof_machine_err;
	}

	/*
	 * Some platforms in SOF, ex: BYT, may not have their platform PM
	 * callbacks set. Increment the usage count so as to
@@ -281,6 +305,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)

	return 0;

sof_machine_err:
	snd_sof_machine_unregister(sdev, plat_data);
fw_trace_err:
	snd_sof_free_trace(sdev);
fw_run_err:
@@ -329,10 +355,6 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)

	sdev->pdata = plat_data;
	sdev->first_boot = true;
	sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED);
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
	sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
#endif
	dev_set_drvdata(dev, sdev);

	/* check all mandatory ops */
@@ -350,9 +372,14 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
	INIT_LIST_HEAD(&sdev->widget_list);
	INIT_LIST_HEAD(&sdev->dai_list);
	INIT_LIST_HEAD(&sdev->route_list);
	INIT_LIST_HEAD(&sdev->ipc_client_list);
	INIT_LIST_HEAD(&sdev->ipc_rx_handler_list);
	INIT_LIST_HEAD(&sdev->fw_state_handler_list);
	spin_lock_init(&sdev->ipc_lock);
	spin_lock_init(&sdev->hw_lock);
	mutex_init(&sdev->power_state_access);
	mutex_init(&sdev->ipc_client_mutex);
	mutex_init(&sdev->client_event_handler_mutex);

	/* set default timeouts if none provided */
	if (plat_data->desc->ipc_timeout == 0)
@@ -364,6 +391,8 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
	else
		sdev->boot_timeout = plat_data->desc->boot_timeout;

	sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED);

	if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) {
		INIT_WORK(&sdev->probe_work, sof_probe_work);
		schedule_work(&sdev->probe_work);
@@ -391,6 +420,12 @@ int snd_sof_device_remove(struct device *dev)
	if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
		cancel_work_sync(&sdev->probe_work);

	/*
	 * Unregister any registered client device first before IPC and debugfs
	 * to allow client drivers to be removed cleanly
	 */
	sof_unregister_clients(sdev);

	/*
	 * Unregister machine driver. This will unbind the snd_card which
	 * will remove the component driver and unload the topology
@@ -443,3 +478,4 @@ MODULE_AUTHOR("Liam Girdwood");
MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("platform:sof-audio");
MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT);
Loading