Blob Blame History Raw
From 97e22cbd0dc318f1cedb3546d2047403506bdc2d Mon Sep 17 00:00:00 2001
From: Bud Liviu-Alexandru <budliviu@gmail.com>
Date: Mon, 4 Oct 2021 18:21:45 +0300
Subject: [PATCH] ASoC: SOF: Make Intel IPC stream ops generic
Mime-version: 1.0
Content-type: text/plain; charset=UTF-8
Content-transfer-encoding: 8bit
Git-commit: 97e22cbd0dc318f1cedb3546d2047403506bdc2d
Patch-mainline: v5.16-rc1
References: jsc#PED-850

This operations should be generic as there is nothing Intel
specific. This works well for NXP i.MX8 stream IPC ops.

We start by moving sof/intel/intel-ipc.c into sof/stream-ipc.c and
rename the functions to be generic.

Notice that we use newly introduced snd_sof_dsp_mailbox_read
instead of sof_mailbox_read, to make sure that we are not
bound to existing MMIO memory access, and we allow platform
to implement their own memory access routines.

Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Bud Liviu-Alexandru <budliviu@gmail.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Daniel Baluta <daniel.baluta@gmail.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20211004152147.1268978-3-daniel.baluta@oss.nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 sound/soc/sof/Makefile          |    2 
 sound/soc/sof/intel/Makefile    |    3 -
 sound/soc/sof/intel/bdw.c       |    8 +--
 sound/soc/sof/intel/byt.c       |   16 +++---
 sound/soc/sof/intel/intel-ipc.c |  103 ----------------------------------------
 sound/soc/sof/intel/pci-tng.c   |    8 +--
 sound/soc/sof/sof-priv.h        |   18 +++---
 sound/soc/sof/stream-ipc.c      |  103 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 129 insertions(+), 132 deletions(-)
 delete mode 100644 sound/soc/sof/intel/intel-ipc.c
 create mode 100644 sound/soc/sof/stream-ipc.c

--- a/sound/soc/sof/Makefile
+++ b/sound/soc/sof/Makefile
@@ -1,7 +1,7 @@
 # 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
+		control.o trace.o utils.o sof-audio.o stream-ipc.o
 
 snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
 
--- a/sound/soc/sof/intel/Makefile
+++ b/sound/soc/sof/intel/Makefile
@@ -3,8 +3,6 @@
 snd-sof-acpi-intel-byt-objs := byt.o
 snd-sof-acpi-intel-bdw-objs := bdw.o
 
-snd-sof-intel-ipc-objs := intel-ipc.o
-
 snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
 				 hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
 				 hda-dai.o hda-bus.o \
@@ -18,7 +16,6 @@ snd-sof-intel-atom-objs := atom.o
 obj-$(CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP) += snd-sof-intel-atom.o
 obj-$(CONFIG_SND_SOC_SOF_BAYTRAIL) += snd-sof-acpi-intel-byt.o
 obj-$(CONFIG_SND_SOC_SOF_BROADWELL) += snd-sof-acpi-intel-bdw.o
-obj-$(CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC) += snd-sof-intel-ipc.o
 obj-$(CONFIG_SND_SOC_SOF_HDA_COMMON) += snd-sof-intel-hda-common.o
 obj-$(CONFIG_SND_SOC_SOF_HDA) += snd-sof-intel-hda.o
 
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -626,8 +626,8 @@ static const struct snd_sof_dsp_ops sof_
 	.get_mailbox_offset = bdw_get_mailbox_offset,
 	.get_window_offset = bdw_get_window_offset,
 
-	.ipc_msg_data	= intel_ipc_msg_data,
-	.ipc_pcm_params	= intel_ipc_pcm_params,
+	.ipc_msg_data	= sof_ipc_msg_data,
+	.ipc_pcm_params	= sof_ipc_pcm_params,
 
 	/* machine driver */
 	.machine_select = bdw_machine_select,
@@ -642,8 +642,8 @@ static const struct snd_sof_dsp_ops sof_
 	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
 
 	/* stream callbacks */
-	.pcm_open	= intel_pcm_open,
-	.pcm_close	= intel_pcm_close,
+	.pcm_open	= sof_stream_pcm_open,
+	.pcm_close	= sof_stream_pcm_close,
 
 	/* Module loading */
 	.load_module    = snd_sof_parse_module_memcpy,
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -240,8 +240,8 @@ static const struct snd_sof_dsp_ops sof_
 	.get_mailbox_offset = atom_get_mailbox_offset,
 	.get_window_offset = atom_get_window_offset,
 
-	.ipc_msg_data	= intel_ipc_msg_data,
-	.ipc_pcm_params	= intel_ipc_pcm_params,
+	.ipc_msg_data	= sof_ipc_msg_data,
+	.ipc_pcm_params	= sof_ipc_pcm_params,
 
 	/* machine driver */
 	.machine_select = atom_machine_select,
@@ -256,8 +256,8 @@ static const struct snd_sof_dsp_ops sof_
 	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
 
 	/* stream callbacks */
-	.pcm_open	= intel_pcm_open,
-	.pcm_close	= intel_pcm_close,
+	.pcm_open	= sof_stream_pcm_open,
+	.pcm_close	= sof_stream_pcm_close,
 
 	/* module loading */
 	.load_module	= snd_sof_parse_module_memcpy,
@@ -322,8 +322,8 @@ static const struct snd_sof_dsp_ops sof_
 	.get_mailbox_offset = atom_get_mailbox_offset,
 	.get_window_offset = atom_get_window_offset,
 
-	.ipc_msg_data	= intel_ipc_msg_data,
-	.ipc_pcm_params	= intel_ipc_pcm_params,
+	.ipc_msg_data	= sof_ipc_msg_data,
+	.ipc_pcm_params	= sof_ipc_pcm_params,
 
 	/* machine driver */
 	.machine_select = atom_machine_select,
@@ -338,8 +338,8 @@ static const struct snd_sof_dsp_ops sof_
 	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
 
 	/* stream callbacks */
-	.pcm_open	= intel_pcm_open,
-	.pcm_close	= intel_pcm_close,
+	.pcm_open	= sof_stream_pcm_open,
+	.pcm_close	= sof_stream_pcm_close,
 
 	/* module loading */
 	.load_module	= snd_sof_parse_module_memcpy,
--- a/sound/soc/sof/intel/intel-ipc.c
+++ /dev/null
@@ -1,103 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
-//
-// This file is provided under a dual BSD/GPLv2 license.  When using or
-// redistributing this file, you may do so under either license.
-//
-// Copyright(c) 2019 Intel Corporation. All rights reserved.
-//
-// Authors: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
-
-/* Intel-specific SOF IPC code */
-
-#include <linux/device.h>
-#include <linux/export.h>
-#include <linux/module.h>
-#include <linux/types.h>
-
-#include <sound/pcm.h>
-#include <sound/sof/stream.h>
-
-#include "../ops.h"
-#include "../sof-priv.h"
-
-struct intel_stream {
-	size_t posn_offset;
-};
-
-/* Mailbox-based Intel IPC implementation */
-int intel_ipc_msg_data(struct snd_sof_dev *sdev,
-		       struct snd_pcm_substream *substream,
-		       void *p, size_t sz)
-{
-	if (!substream || !sdev->stream_box.size) {
-		sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz);
-	} else {
-		struct intel_stream *stream = substream->runtime->private_data;
-
-		/* The stream might already be closed */
-		if (!stream)
-			return -ESTRPIPE;
-
-		sof_mailbox_read(sdev, stream->posn_offset, p, sz);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_NS(intel_ipc_msg_data, SND_SOC_SOF_INTEL_HIFI_EP_IPC);
-
-int intel_ipc_pcm_params(struct snd_sof_dev *sdev,
-			 struct snd_pcm_substream *substream,
-			 const struct sof_ipc_pcm_params_reply *reply)
-{
-	struct intel_stream *stream = substream->runtime->private_data;
-	size_t posn_offset = reply->posn_offset;
-
-	/* check if offset is overflow or it is not aligned */
-	if (posn_offset > sdev->stream_box.size ||
-	    posn_offset % sizeof(struct sof_ipc_stream_posn) != 0)
-		return -EINVAL;
-
-	stream->posn_offset = sdev->stream_box.offset + posn_offset;
-
-	dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu",
-		substream->stream, stream->posn_offset);
-
-	return 0;
-}
-EXPORT_SYMBOL_NS(intel_ipc_pcm_params, SND_SOC_SOF_INTEL_HIFI_EP_IPC);
-
-int intel_pcm_open(struct snd_sof_dev *sdev,
-		   struct snd_pcm_substream *substream)
-{
-	struct intel_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL);
-
-	if (!stream)
-		return -ENOMEM;
-
-	/* binding pcm substream to hda stream */
-	substream->runtime->private_data = stream;
-
-	/* align to DMA minimum transfer size */
-	snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
-
-	/* avoid circular buffer wrap in middle of period */
-	snd_pcm_hw_constraint_integer(substream->runtime,
-				      SNDRV_PCM_HW_PARAM_PERIODS);
-
-	return 0;
-}
-EXPORT_SYMBOL_NS(intel_pcm_open, SND_SOC_SOF_INTEL_HIFI_EP_IPC);
-
-int intel_pcm_close(struct snd_sof_dev *sdev,
-		    struct snd_pcm_substream *substream)
-{
-	struct intel_stream *stream = substream->runtime->private_data;
-
-	substream->runtime->private_data = NULL;
-	kfree(stream);
-
-	return 0;
-}
-EXPORT_SYMBOL_NS(intel_pcm_close, SND_SOC_SOF_INTEL_HIFI_EP_IPC);
-
-MODULE_LICENSE("Dual BSD/GPL");
--- a/sound/soc/sof/intel/pci-tng.c
+++ b/sound/soc/sof/intel/pci-tng.c
@@ -156,8 +156,8 @@ const struct snd_sof_dsp_ops sof_tng_ops
 	.get_mailbox_offset = atom_get_mailbox_offset,
 	.get_window_offset = atom_get_window_offset,
 
-	.ipc_msg_data	= intel_ipc_msg_data,
-	.ipc_pcm_params	= intel_ipc_pcm_params,
+	.ipc_msg_data	= sof_ipc_msg_data,
+	.ipc_pcm_params	= sof_ipc_pcm_params,
 
 	/* machine driver */
 	.machine_select = atom_machine_select,
@@ -172,8 +172,8 @@ const struct snd_sof_dsp_ops sof_tng_ops
 	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
 
 	/* stream callbacks */
-	.pcm_open	= intel_pcm_open,
-	.pcm_close	= intel_pcm_close,
+	.pcm_open	= sof_stream_pcm_open,
+	.pcm_close	= sof_stream_pcm_close,
 
 	/* module loading */
 	.load_module	= snd_sof_parse_module_memcpy,
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -600,17 +600,17 @@ int sof_block_read(struct snd_sof_dev *s
 
 int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id);
 
-int intel_ipc_msg_data(struct snd_sof_dev *sdev,
+int sof_ipc_msg_data(struct snd_sof_dev *sdev,
+		     struct snd_pcm_substream *substream,
+		     void *p, size_t sz);
+int sof_ipc_pcm_params(struct snd_sof_dev *sdev,
 		       struct snd_pcm_substream *substream,
-		       void *p, size_t sz);
-int intel_ipc_pcm_params(struct snd_sof_dev *sdev,
-			 struct snd_pcm_substream *substream,
-			 const struct sof_ipc_pcm_params_reply *reply);
+		       const struct sof_ipc_pcm_params_reply *reply);
 
-int intel_pcm_open(struct snd_sof_dev *sdev,
-		   struct snd_pcm_substream *substream);
-int intel_pcm_close(struct snd_sof_dev *sdev,
-		    struct snd_pcm_substream *substream);
+int sof_stream_pcm_open(struct snd_sof_dev *sdev,
+			struct snd_pcm_substream *substream);
+int sof_stream_pcm_close(struct snd_sof_dev *sdev,
+			 struct snd_pcm_substream *substream);
 
 int sof_machine_check(struct snd_sof_dev *sdev);
 #endif
--- /dev/null
+++ b/sound/soc/sof/stream-ipc.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license.  When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2019 Intel Corporation. All rights reserved.
+//
+// Authors: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+
+/* Generic SOF IPC code */
+
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <sound/pcm.h>
+#include <sound/sof/stream.h>
+
+#include "ops.h"
+#include "sof-priv.h"
+
+struct sof_stream {
+	size_t posn_offset;
+};
+
+/* Mailbox-based Generic IPC implementation */
+int sof_ipc_msg_data(struct snd_sof_dev *sdev,
+		     struct snd_pcm_substream *substream,
+		     void *p, size_t sz)
+{
+	if (!substream || !sdev->stream_box.size) {
+		snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, p, sz);
+	} else {
+		struct sof_stream *stream = substream->runtime->private_data;
+
+		/* The stream might already be closed */
+		if (!stream)
+			return -ESTRPIPE;
+
+		snd_sof_dsp_mailbox_read(sdev, stream->posn_offset, p, sz);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(sof_ipc_msg_data);
+
+int sof_ipc_pcm_params(struct snd_sof_dev *sdev,
+		       struct snd_pcm_substream *substream,
+		       const struct sof_ipc_pcm_params_reply *reply)
+{
+	struct sof_stream *stream = substream->runtime->private_data;
+	size_t posn_offset = reply->posn_offset;
+
+	/* check if offset is overflow or it is not aligned */
+	if (posn_offset > sdev->stream_box.size ||
+	    posn_offset % sizeof(struct sof_ipc_stream_posn) != 0)
+		return -EINVAL;
+
+	stream->posn_offset = sdev->stream_box.offset + posn_offset;
+
+	dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu",
+		substream->stream, stream->posn_offset);
+
+	return 0;
+}
+EXPORT_SYMBOL(sof_ipc_pcm_params);
+
+int sof_stream_pcm_open(struct snd_sof_dev *sdev,
+			struct snd_pcm_substream *substream)
+{
+	struct sof_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL);
+
+	if (!stream)
+		return -ENOMEM;
+
+	/* binding pcm substream to hda stream */
+	substream->runtime->private_data = stream;
+
+	/* align to DMA minimum transfer size */
+	snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
+
+	/* avoid circular buffer wrap in middle of period */
+	snd_pcm_hw_constraint_integer(substream->runtime,
+				      SNDRV_PCM_HW_PARAM_PERIODS);
+
+	return 0;
+}
+EXPORT_SYMBOL(sof_stream_pcm_open);
+
+int sof_stream_pcm_close(struct snd_sof_dev *sdev,
+			 struct snd_pcm_substream *substream)
+{
+	struct sof_stream *stream = substream->runtime->private_data;
+
+	substream->runtime->private_data = NULL;
+	kfree(stream);
+
+	return 0;
+}
+EXPORT_SYMBOL(sof_stream_pcm_close);
+
+MODULE_LICENSE("Dual BSD/GPL");