From: Bud Liviu-Alexandru Date: Mon, 4 Oct 2021 15:21:45 +0000 (+0300) Subject: ASoC: SOF: Make Intel IPC stream ops generic X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=97e22cbd0dc318f1cedb3546d2047403506bdc2d;p=linux.git ASoC: SOF: Make Intel IPC stream ops generic 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 Signed-off-by: Bud Liviu-Alexandru Reviewed-by: Pierre-Louis Bossart Reviewed-by: Daniel Baluta Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20211004152147.1268978-3-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index bdea0faac117e..c5b97c66a9f16 100644 --- 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 diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index 9635dd47a17d8..1f473d4d8416e 100644 --- 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 diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 9c06b92fcb5e5..2c09a523288e5 100644 --- 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_bdw_ops = { .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_bdw_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, diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 8c500a83babc6..e2fa08f1ae74e 100644 --- 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_byt_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, @@ -256,8 +256,8 @@ static const struct snd_sof_dsp_ops sof_byt_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, @@ -322,8 +322,8 @@ static const struct snd_sof_dsp_ops sof_cht_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, @@ -338,8 +338,8 @@ static const struct snd_sof_dsp_ops sof_cht_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, diff --git a/sound/soc/sof/intel/intel-ipc.c b/sound/soc/sof/intel/intel-ipc.c deleted file mode 100644 index df37187c8427d..0000000000000 --- 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 - -/* Intel-specific SOF IPC code */ - -#include -#include -#include -#include - -#include -#include - -#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"); diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index 8042ac76ec15b..18eb41b8a8f4a 100644 --- 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, diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index f6a8478347bb2..1a12355d8f414 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -582,17 +582,17 @@ int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, 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); - -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); + const struct sof_ipc_pcm_params_reply *reply); + +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); diff --git a/sound/soc/sof/stream-ipc.c b/sound/soc/sof/stream-ipc.c new file mode 100644 index 0000000000000..15a55851faeb3 --- /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 + +/* Generic SOF IPC code */ + +#include +#include +#include +#include + +#include +#include + +#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");