[Sound-open-firmware] [PATCH 0/4] Introduce new SOF helpers
From: Daniel Baluta daniel.baluta@nxp.com
This patchseries adds new helpers in order to reduce code duplication and prepare for compress audio support with SOF.
Bud Liviu-Alexandru (1): ASoC: SOF: Make Intel IPC stream ops generic
Daniel Baluta (3): ASoC: SOF: Introduce snd_sof_mailbox_read / snd_sof_mailbox_write callbacks ASoC: SOF: imx: Use newly introduced generic IPC stream ops ASoC: SOF: Introduce fragment elapsed notification API
sound/soc/sof/Kconfig | 4 ++ sound/soc/sof/Makefile | 3 +- sound/soc/sof/compress.c | 51 +++++++++++++++++++ sound/soc/sof/imx/Kconfig | 2 + sound/soc/sof/imx/imx8.c | 39 +++++++------- sound/soc/sof/imx/imx8m.c | 26 ++++------ sound/soc/sof/intel/Makefile | 3 -- sound/soc/sof/intel/apl.c | 4 ++ sound/soc/sof/intel/bdw.c | 12 +++-- sound/soc/sof/intel/byt.c | 24 ++++++--- sound/soc/sof/intel/cnl.c | 4 ++ sound/soc/sof/intel/icl.c | 4 ++ sound/soc/sof/intel/pci-tng.c | 12 +++-- sound/soc/sof/intel/tgl.c | 4 ++ sound/soc/sof/ipc.c | 6 ++- sound/soc/sof/ops.h | 15 ++++++ sound/soc/sof/pcm.c | 7 ++- sound/soc/sof/sof-audio.h | 11 +++- sound/soc/sof/sof-priv.h | 28 ++++++---- .../sof/{intel/intel-ipc.c => stream-ipc.c} | 50 +++++++++--------- sound/soc/sof/topology.c | 6 ++- 21 files changed, 218 insertions(+), 97 deletions(-) create mode 100644 sound/soc/sof/compress.c rename sound/soc/sof/{intel/intel-ipc.c => stream-ipc.c} (58%)
From: Daniel Baluta daniel.baluta@nxp.com
We need to introduce snd_sof_mailbox_{read/write} in order to provide a generic way for mailbox access. These routines are optional, each platform can implement their own specific routines.
So far, all platforms use mmapped I/O thus they can use custom made routines sof_mailbox_read / sof_mailbox_write that use MMIO.
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: Péter Ujfalusi peter.ujfalusi@linux.intel.com --- sound/soc/sof/imx/imx8.c | 8 ++++++++ sound/soc/sof/imx/imx8m.c | 4 ++++ sound/soc/sof/intel/apl.c | 4 ++++ sound/soc/sof/intel/bdw.c | 4 ++++ sound/soc/sof/intel/byt.c | 8 ++++++++ sound/soc/sof/intel/cnl.c | 4 ++++ sound/soc/sof/intel/icl.c | 4 ++++ sound/soc/sof/intel/pci-tng.c | 4 ++++ sound/soc/sof/intel/tgl.c | 4 ++++ sound/soc/sof/ops.h | 15 +++++++++++++++ sound/soc/sof/sof-priv.h | 8 ++++++++ 11 files changed, 67 insertions(+)
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 0247806be8d7..75baa5209a89 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -428,6 +428,10 @@ struct snd_sof_dsp_ops sof_imx8_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = imx8_send_msg, .fw_ready = sof_fw_ready, @@ -475,6 +479,10 @@ struct snd_sof_dsp_ops sof_imx8x_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = imx8_send_msg, .fw_ready = sof_fw_ready, diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index 08d29f095d51..c7d3d898d5a4 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -291,6 +291,10 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = imx8m_send_msg, .fw_ready = sof_fw_ready, diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index e6a1f6532547..917f78cf6daf 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -42,6 +42,10 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = hda_dsp_ipc_irq_thread,
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index d09275417749..9c06b92fcb5e 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -616,6 +616,10 @@ static const struct snd_sof_dsp_ops sof_bdw_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* ipc */ .send_msg = bdw_send_msg, .fw_ready = sof_fw_ready, diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 8f60c72fee7e..8c500a83babc 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -226,6 +226,10 @@ static const struct snd_sof_dsp_ops sof_byt_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_handler = atom_irq_handler, .irq_thread = atom_irq_thread, @@ -304,6 +308,10 @@ static const struct snd_sof_dsp_ops sof_cht_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_handler = atom_irq_handler, .irq_thread = atom_irq_thread, diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 430a268e6b26..3957e2b3db32 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -247,6 +247,10 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = cnl_ipc_irq_thread,
diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c index 38a40c03c9da..0b2cc331d55b 100644 --- a/sound/soc/sof/intel/icl.c +++ b/sound/soc/sof/intel/icl.c @@ -41,6 +41,10 @@ const struct snd_sof_dsp_ops sof_icl_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = cnl_ipc_irq_thread,
diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index 3d6d013844d7..8042ac76ec15 100644 --- a/sound/soc/sof/intel/pci-tng.c +++ b/sound/soc/sof/intel/pci-tng.c @@ -142,6 +142,10 @@ const struct snd_sof_dsp_ops sof_tng_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_handler = atom_irq_handler, .irq_thread = atom_irq_thread, diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index 664a11aaada2..48da8e7a67bc 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -37,6 +37,10 @@ const struct snd_sof_dsp_ops sof_tgl_ops = { .block_read = sof_block_read, .block_write = sof_block_write,
+ /* Mailbox IO */ + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + /* doorbell */ .irq_thread = cnl_ipc_irq_thread,
diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index a93aa5b943b2..1a5cc8ad4aca 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -322,6 +322,21 @@ static inline int snd_sof_dsp_block_write(struct snd_sof_dev *sdev, return sof_ops(sdev)->block_write(sdev, blk_type, offset, src, bytes); }
+/* mailbox IO */ +static inline void snd_sof_dsp_mailbox_read(struct snd_sof_dev *sdev, + u32 offset, void *dest, size_t bytes) +{ + if (sof_ops(sdev)->mailbox_read) + sof_ops(sdev)->mailbox_read(sdev, offset, dest, bytes); +} + +static inline void snd_sof_dsp_mailbox_write(struct snd_sof_dev *sdev, + u32 offset, void *src, size_t bytes) +{ + if (sof_ops(sdev)->mailbox_write) + sof_ops(sdev)->mailbox_write(sdev, offset, src, bytes); +} + /* ipc */ static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 1289e2efeb62..388e71bcacf8 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -145,6 +145,14 @@ struct snd_sof_dsp_ops { enum snd_sof_fw_blk_type type, u32 offset, void *src, size_t size); /* mandatory */
+ /* Mailbox IO */ + void (*mailbox_read)(struct snd_sof_dev *sof_dev, + u32 offset, void *dest, + size_t size); /* optional */ + void (*mailbox_write)(struct snd_sof_dev *sof_dev, + u32 offset, void *src, + size_t size); /* optional */ + /* doorbell */ irqreturn_t (*irq_handler)(int irq, void *context); /* optional */ irqreturn_t (*irq_thread)(int irq, void *context); /* optional */
From: Bud Liviu-Alexandru budliviu@gmail.com
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 --- 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/pci-tng.c | 8 +-- sound/soc/sof/sof-priv.h | 20 ++++---- .../sof/{intel/intel-ipc.c => stream-ipc.c} | 50 +++++++++---------- 7 files changed, 52 insertions(+), 55 deletions(-) rename sound/soc/sof/{intel/intel-ipc.c => stream-ipc.c} (58%)
diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index bdea0faac117..c5b97c66a9f1 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 9635dd47a17d..1f473d4d8416 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 9c06b92fcb5e..2c09a523288e 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 8c500a83babc..e2fa08f1ae74 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/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index 8042ac76ec15..18eb41b8a8f4 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 388e71bcacf8..3927015c8a96 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -576,17 +576,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/intel/intel-ipc.c b/sound/soc/sof/stream-ipc.c similarity index 58% rename from sound/soc/sof/intel/intel-ipc.c rename to sound/soc/sof/stream-ipc.c index df37187c8427..15a55851faeb 100644 --- a/sound/soc/sof/intel/intel-ipc.c +++ b/sound/soc/sof/stream-ipc.c @@ -7,7 +7,7 @@ // // Authors: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com
-/* Intel-specific SOF IPC code */ +/* Generic SOF IPC code */
#include <linux/device.h> #include <linux/export.h> @@ -17,39 +17,39 @@ #include <sound/pcm.h> #include <sound/sof/stream.h>
-#include "../ops.h" -#include "../sof-priv.h" +#include "ops.h" +#include "sof-priv.h"
-struct intel_stream { +struct sof_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) +/* 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) { - sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); + snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); } else { - struct intel_stream *stream = substream->runtime->private_data; + struct sof_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); + snd_sof_dsp_mailbox_read(sdev, stream->posn_offset, p, sz); }
return 0; } -EXPORT_SYMBOL_NS(intel_ipc_msg_data, SND_SOC_SOF_INTEL_HIFI_EP_IPC); +EXPORT_SYMBOL(sof_ipc_msg_data);
-int intel_ipc_pcm_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply) +int sof_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; + 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 */ @@ -64,12 +64,12 @@ int intel_ipc_pcm_params(struct snd_sof_dev *sdev,
return 0; } -EXPORT_SYMBOL_NS(intel_ipc_pcm_params, SND_SOC_SOF_INTEL_HIFI_EP_IPC); +EXPORT_SYMBOL(sof_ipc_pcm_params);
-int intel_pcm_open(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) { - struct intel_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL); + struct sof_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL);
if (!stream) return -ENOMEM; @@ -86,18 +86,18 @@ int intel_pcm_open(struct snd_sof_dev *sdev,
return 0; } -EXPORT_SYMBOL_NS(intel_pcm_open, SND_SOC_SOF_INTEL_HIFI_EP_IPC); +EXPORT_SYMBOL(sof_stream_pcm_open);
-int intel_pcm_close(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) { - struct intel_stream *stream = substream->runtime->private_data; + struct sof_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); +EXPORT_SYMBOL(sof_stream_pcm_close);
MODULE_LICENSE("Dual BSD/GPL");
From: Daniel Baluta daniel.baluta@nxp.com
This makes IMX use the newly introduced generic IPC ops instead of imx specific ones, and removes the old IMX ipc ops, as they are no longer needed.
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: Péter Ujfalusi peter.ujfalusi@linux.intel.com --- sound/soc/sof/imx/imx8.c | 31 ++++++++++++------------------- sound/soc/sof/imx/imx8m.c | 22 +++++----------------- 2 files changed, 17 insertions(+), 36 deletions(-)
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 75baa5209a89..dd59a74480d6 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -376,21 +376,6 @@ static int imx8_get_bar_index(struct snd_sof_dev *sdev, u32 type) } }
-static int imx8_ipc_msg_data(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - void *p, size_t sz) -{ - sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); - return 0; -} - -static int imx8_ipc_pcm_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply) -{ - return 0; -} - static struct snd_soc_dai_driver imx8_dai[] = { { .name = "esai0", @@ -438,8 +423,8 @@ struct snd_sof_dsp_ops sof_imx8_ops = { .get_mailbox_offset = imx8_get_mailbox_offset, .get_window_offset = imx8_get_window_offset,
- .ipc_msg_data = imx8_ipc_msg_data, - .ipc_pcm_params = imx8_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params,
/* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -451,6 +436,10 @@ struct snd_sof_dsp_ops sof_imx8_ops = { .dbg_dump = imx8_dump, .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
+ /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, + /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops,
@@ -489,8 +478,8 @@ struct snd_sof_dsp_ops sof_imx8x_ops = { .get_mailbox_offset = imx8_get_mailbox_offset, .get_window_offset = imx8_get_window_offset,
- .ipc_msg_data = imx8_ipc_msg_data, - .ipc_pcm_params = imx8_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params,
/* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -502,6 +491,10 @@ struct snd_sof_dsp_ops sof_imx8x_ops = { .dbg_dump = imx8_dump, .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
+ /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, + /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops,
diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index c7d3d898d5a4..e4618980cf8b 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -239,21 +239,6 @@ static int imx8m_get_bar_index(struct snd_sof_dev *sdev, u32 type) } }
-static int imx8m_ipc_msg_data(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - void *p, size_t sz) -{ - sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); - return 0; -} - -static int imx8m_ipc_pcm_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply) -{ - return 0; -} - static struct snd_soc_dai_driver imx8m_dai[] = { { .name = "sai1", @@ -301,8 +286,8 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { .get_mailbox_offset = imx8m_get_mailbox_offset, .get_window_offset = imx8m_get_window_offset,
- .ipc_msg_data = imx8m_ipc_msg_data, - .ipc_pcm_params = imx8m_ipc_pcm_params, + .ipc_msg_data = sof_ipc_msg_data, + .ipc_pcm_params = sof_ipc_pcm_params,
/* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -314,6 +299,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { .dbg_dump = imx8_dump, .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
+ /* stream callbacks */ + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops,
From: Daniel Baluta daniel.baluta@nxp.com
This patch prepares the introduction of the compress API with SOF.
After each fragment is accepted by the DSP we need to inform the userspace applications that they can send the next fragment. This is done via snd_compr_fragment_elapsed.
Similar with the PCM case, in order to avoid sending an IPC before the previous IPC is handled we need to schedule a delayed work to call snd_compr_fragment_elapsed().
See snd_sof_pcm_period_elapsed.
To sum up this patch offers the following API to SOF code: * snd_sof_compr_init_elapsed_work * snd_sof_compr_fragment_elapsed
Note that implementation for compressed function is in a new file selected via CONFIG_SND_SOC_SOF_COMPRESS invisible config option. This option is automatically selected for platforms that support the compress interface. For now only i.MX8 platforms support this.
For symmetry we introduce snd_sof_pcm_init_elapsed_work to setup the work struct for PCM case.
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: Paul Olaru paul.olaru@oss.nxp.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com --- sound/soc/sof/Kconfig | 4 +++ sound/soc/sof/Makefile | 1 + sound/soc/sof/compress.c | 51 +++++++++++++++++++++++++++++++++++++++ sound/soc/sof/imx/Kconfig | 2 ++ sound/soc/sof/ipc.c | 6 +++-- sound/soc/sof/pcm.c | 7 +++++- sound/soc/sof/sof-audio.h | 11 ++++++++- sound/soc/sof/topology.c | 6 +++-- 8 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 sound/soc/sof/compress.c
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index 94d1a859fedc..6bb4db87af03 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -46,6 +46,10 @@ config SND_SOC_SOF_OF required to enable i.MX8 devices. Say Y if you need this option. If unsure select "N".
+config SND_SOC_SOF_COMPRESS + tristate + select SND_SOC_COMPRESS + config SND_SOC_SOF_DEBUG_PROBES bool "SOF enable data probing" select SND_SOC_COMPRESS diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index c5b97c66a9f1..06e5f49f7ee8 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -4,6 +4,7 @@ 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
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 diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c new file mode 100644 index 000000000000..01ca85f0b87f --- /dev/null +++ b/sound/soc/sof/compress.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright 2021 NXP +// +// Author: Daniel Baluta daniel.baluta@nxp.com + +#include <sound/soc.h> +#include <sound/sof.h> +#include <sound/compress_driver.h> +#include "sof-audio.h" +#include "sof-priv.h" + +static void snd_sof_compr_fragment_elapsed_work(struct work_struct *work) +{ + struct snd_sof_pcm_stream *sps = + container_of(work, struct snd_sof_pcm_stream, + period_elapsed_work); + + snd_compr_fragment_elapsed(sps->cstream); +} + +void snd_sof_compr_init_elapsed_work(struct work_struct *work) +{ + INIT_WORK(work, snd_sof_compr_fragment_elapsed_work); +} + +/* + * sof compr fragment elapse, this could be called in irq thread context + */ +void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) +{ + struct snd_soc_component *component; + struct snd_soc_pcm_runtime *rtd; + struct snd_sof_pcm *spcm; + + if (!cstream) + return; + + rtd = cstream->private_data; + component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); + + spcm = snd_sof_find_spcm_dai(component, rtd); + if (!spcm) { + dev_err(component->dev, + "fragment elapsed called for unknown stream!\n"); + return; + } + + /* use the same workqueue-based solution as for PCM, cf. snd_sof_pcm_elapsed */ + schedule_work(&spcm->stream[cstream->direction].period_elapsed_work); +} diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 49d605cb09a5..34cf228c188f 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -38,6 +38,7 @@ config SND_SOC_SOF_IMX8 tristate select SND_SOC_SOF_IMX_COMMON select SND_SOC_SOF_XTENSA + select SND_SOC_SOF_COMPRESS help This option is not user-selectable but automagically handled by 'select' statements at a higher level. @@ -54,6 +55,7 @@ config SND_SOC_SOF_IMX8M tristate select SND_SOC_SOF_IMX_COMMON select SND_SOC_SOF_XTENSA + select SND_SOC_SOF_COMPRESS help This option is not user-selectable but automagically handled by 'select' statements at a higher level. diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 53593df95155..1efc2c395c54 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -539,8 +539,10 @@ static void ipc_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id)
memcpy(&stream->posn, &posn, sizeof(posn));
- /* only inform ALSA for period_wakeup mode */ - if (!stream->substream->runtime->no_period_wakeup) + if (spcm->pcm.compress) + snd_sof_compr_fragment_elapsed(stream->cstream); + else if (!stream->substream->runtime->no_period_wakeup) + /* only inform ALSA for period_wakeup mode */ snd_sof_pcm_period_elapsed(stream->substream); }
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 374df2dfa816..fa0bfcd2474e 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -57,7 +57,7 @@ static int sof_pcm_dsp_params(struct snd_sof_pcm *spcm, struct snd_pcm_substream /* * sof pcm period elapse work */ -void snd_sof_pcm_period_elapsed_work(struct work_struct *work) +static void snd_sof_pcm_period_elapsed_work(struct work_struct *work) { struct snd_sof_pcm_stream *sps = container_of(work, struct snd_sof_pcm_stream, @@ -66,6 +66,11 @@ void snd_sof_pcm_period_elapsed_work(struct work_struct *work) snd_pcm_period_elapsed(sps->substream); }
+void snd_sof_pcm_init_elapsed_work(struct work_struct *work) +{ + INIT_WORK(work, snd_sof_pcm_period_elapsed_work); +} + /* * sof pcm period elapse, this could be called at irq thread context. */ diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 149b3dbcddd1..3f16611fbca7 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -36,6 +36,7 @@ struct snd_sof_pcm_stream { struct snd_dma_buffer page_table; struct sof_ipc_stream_posn posn; struct snd_pcm_substream *substream; + struct snd_compr_stream *cstream; struct work_struct period_elapsed_work; struct snd_soc_dapm_widget_list *list; /* list of connected DAPM widgets */ bool d0i3_compatible; /* DSP can be in D0I3 when this pcm is opened */ @@ -231,7 +232,15 @@ struct snd_sof_pcm *snd_sof_find_spcm_pcm_id(struct snd_soc_component *scomp, const struct sof_ipc_pipe_new *snd_sof_pipeline_find(struct snd_sof_dev *sdev, int pipeline_id); void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream); -void snd_sof_pcm_period_elapsed_work(struct work_struct *work); +void snd_sof_pcm_init_elapsed_work(struct work_struct *work); + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS) +void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream); +void snd_sof_compr_init_elapsed_work(struct work_struct *work); +#else +static inline void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) { } +static inline void snd_sof_compr_init_elapsed_work(struct work_struct *work) { } +#endif
/* * Mixer IPC diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 44d60081bc26..43bd2f18c1c2 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2581,8 +2581,10 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
for_each_pcm_streams(stream) { spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED; - INIT_WORK(&spcm->stream[stream].period_elapsed_work, - snd_sof_pcm_period_elapsed_work); + if (pcm->compress) + snd_sof_compr_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); + else + snd_sof_pcm_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); }
spcm->pcm = *pcm;
On Mon, 4 Oct 2021 18:21:43 +0300, Daniel Baluta wrote:
From: Daniel Baluta daniel.baluta@nxp.com
This patchseries adds new helpers in order to reduce code duplication and prepare for compress audio support with SOF.
Bud Liviu-Alexandru (1): ASoC: SOF: Make Intel IPC stream ops generic
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: SOF: Introduce snd_sof_mailbox_read / snd_sof_mailbox_write callbacks commit: f71f59dd450813684d838e0c1d6602186b7d2d8f [2/4] ASoC: SOF: Make Intel IPC stream ops generic commit: 97e22cbd0dc318f1cedb3546d2047403506bdc2d [3/4] ASoC: SOF: imx: Use newly introduced generic IPC stream ops commit: 40834190aa81270c52104fa9c82a1cae4bd1d359 [4/4] ASoC: SOF: Introduce fragment elapsed notification API commit: 858f7a5c45cacbf9965c4735330ee34baa0728f4
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Daniel Baluta
-
Mark Brown