From 6ea7742a283b7013f326f622071e72aa53fbbf49 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 5 Apr 2019 09:04:24 +0200 Subject: [PATCH 01/11] ASoC: SOF: ipc: remove a left-over logging entry A recent commit f3adfd66c97c ("ASoC:sof: remove duplicate posn message in kernel log")' removed a redundant logging entry in ipc_period_elapsed() but it missed a similar ont in ipc_xrun(). Remove the latter one too. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/ipc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index c783c9522e5a0d..7e0aa9a1b49634 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -493,9 +493,6 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id) posn_offset = spcm->posn_offset[direction]; snd_sof_dsp_mailbox_read(sdev, posn_offset, &posn, sizeof(posn)); - - dev_dbg(sdev->dev, "posn mailbox: posn offset is 0x%x", - posn_offset); } dev_dbg(sdev->dev, "posn XRUN: host %llx comp %d size %d\n", From 9bd9550a3691277e285d1a8f33c7564952365820 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 5 Apr 2019 09:06:46 +0200 Subject: [PATCH 02/11] ASoC: SOF: ipc: remove a redundant test Even if the stream position IPC from the DSP isn't using the stream mailbox, there is no need to read the complete message to get a message ID, it must be the same as the one, obtained earlier from the same mailbox. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/ipc.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 7e0aa9a1b49634..fc998d244b54b8 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -428,17 +428,7 @@ static void ipc_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id) u32 posn_offset; int direction; - /* check if we have stream box */ - if (sdev->stream_box.size == 0) { - /* read back full message */ - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &posn, - sizeof(posn)); - - spcm = snd_sof_find_spcm_comp(sdev, posn.comp_id, &direction); - } else { - spcm = snd_sof_find_spcm_comp(sdev, msg_id, &direction); - } - + spcm = snd_sof_find_spcm_comp(sdev, msg_id, &direction); if (!spcm) { dev_err(sdev->dev, "error: period elapsed for unknown stream, msg_id %d\n", @@ -446,11 +436,15 @@ static void ipc_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id) return; } - /* have stream box read from stream box */ if (sdev->stream_box.size != 0) { + /* have stream box read from stream box */ posn_offset = spcm->posn_offset[direction]; snd_sof_dsp_mailbox_read(sdev, posn_offset, &posn, sizeof(posn)); + } else { + /* read back full message */ + snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &posn, + sizeof(posn)); } dev_dbg(sdev->dev, "posn : host 0x%llx dai 0x%llx wall 0x%llx\n", @@ -471,28 +465,22 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id) u32 posn_offset; int direction; - /* check if we have stream MMIO on this platform */ - if (sdev->stream_box.size == 0) { - /* read back full message */ - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &posn, - sizeof(posn)); - - spcm = snd_sof_find_spcm_comp(sdev, posn.comp_id, &direction); - } else { - spcm = snd_sof_find_spcm_comp(sdev, msg_id, &direction); - } - + spcm = snd_sof_find_spcm_comp(sdev, msg_id, &direction); if (!spcm) { dev_err(sdev->dev, "error: XRUN for unknown stream, msg_id %d\n", msg_id); return; } - /* have stream box read from stream box */ if (sdev->stream_box.size != 0) { + /* have stream box read from stream box */ posn_offset = spcm->posn_offset[direction]; snd_sof_dsp_mailbox_read(sdev, posn_offset, &posn, sizeof(posn)); + } else { + /* read back full message */ + snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &posn, + sizeof(posn)); } dev_dbg(sdev->dev, "posn XRUN: host %llx comp %d size %d\n", From 5baa5a730ae20247126f6ba9fbff757153ffa85c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 29 Mar 2019 17:48:11 +0100 Subject: [PATCH 03/11] ASoC: SOF: IPC: remove direct mailbox reading from SOF core Obtaining data from the DSP by reading the mailbox is Intel-specific, move them from the SOF core to Intel-specific drivers. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/Kconfig | 8 +++ sound/soc/sof/intel/Makefile | 4 ++ sound/soc/sof/intel/apl.c | 3 ++ sound/soc/sof/intel/bdw.c | 7 +++ sound/soc/sof/intel/byt.c | 21 ++++++++ sound/soc/sof/intel/cnl.c | 3 ++ sound/soc/sof/intel/hda-ipc.c | 47 ++++++++++++++++ sound/soc/sof/intel/hda-stream.c | 21 ++++++-- sound/soc/sof/intel/hda.h | 15 +++++- sound/soc/sof/intel/intel-ipc.c | 93 ++++++++++++++++++++++++++++++++ sound/soc/sof/intel/shim.h | 4 ++ sound/soc/sof/ipc.c | 43 +++++---------- sound/soc/sof/ops.h | 22 ++++++++ sound/soc/sof/pcm.c | 33 ++++++------ sound/soc/sof/sof-priv.h | 23 +++++++- 15 files changed, 294 insertions(+), 53 deletions(-) create mode 100644 sound/soc/sof/intel/intel-ipc.c diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index 875bd09a32b5fe..9deb126f5d15a2 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -31,9 +31,16 @@ config SND_SOC_SOF_INTEL_PCI This option is not user-selectable but automagically handled by 'select' statements at a higher level +config SND_SOC_SOF_INTEL_HIFI_EP_IPC + tristate + help + This option is not user-selectable but automagically handled by + 'select' statements at a higher level + config SND_SOC_SOF_INTEL_ATOM_HIFI_EP tristate select SND_SOC_INTEL_COMMON + select SND_SOC_SOF_INTEL_HIFI_EP_IPC help This option is not user-selectable but automagically handled by 'select' statements at a higher level @@ -91,6 +98,7 @@ config SND_SOC_SOF_BROADWELL_SUPPORT config SND_SOC_SOF_BROADWELL tristate select SND_SOC_SOF_INTEL_COMMON + select SND_SOC_SOF_INTEL_HIFI_EP_IPC help This option is not user-selectable but automagically handled by 'select' statements at a higher level diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index 7a52b89eea863a..03b22924d0c4eb 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -5,6 +5,9 @@ ccflags-y += -DDEBUG snd-sof-intel-byt-objs := byt.o snd-sof-intel-hsw-objs := hsw.o snd-sof-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 hda-loader-skl.o \ @@ -15,5 +18,6 @@ snd-sof-intel-hda-objs := hda-codec.o obj-$(CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP) += snd-sof-intel-byt.o obj-$(CONFIG_SND_SOC_SOF_HASWELL) += snd-sof-intel-hsw.o obj-$(CONFIG_SND_SOC_SOF_BROADWELL) += snd-sof-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/apl.c b/sound/soc/sof/intel/apl.c index 654d74175d2704..2fe7fe2ac55369 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -52,6 +52,9 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .send_msg = hda_dsp_ipc_send_msg, .fw_ready = hda_dsp_ipc_fw_ready, + .ipc_msg_data = hda_ipc_msg_data, + .ipc_pcm_params = hda_ipc_pcm_params, + /* debug */ .debug_map = apl_dsp_debugfs, .debug_map_count = ARRAY_SIZE(apl_dsp_debugfs), diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 2483eaa5957105..5210dd77cced15 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -674,11 +674,18 @@ const struct snd_sof_dsp_ops sof_bdw_ops = { .send_msg = bdw_send_msg, .fw_ready = bdw_fw_ready, + .ipc_msg_data = intel_ipc_msg_data, + .ipc_pcm_params = intel_ipc_pcm_params, + /* debug */ .debug_map = bdw_debugfs, .debug_map_count = ARRAY_SIZE(bdw_debugfs), .dbg_dump = bdw_dump, + /* stream callbacks */ + .pcm_open = intel_pcm_open, + .pcm_close = intel_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 2975cbea950642..0bd2a3c38df8fd 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -613,11 +613,18 @@ const struct snd_sof_dsp_ops sof_tng_ops = { .send_msg = byt_send_msg, .fw_ready = byt_fw_ready, + .ipc_msg_data = intel_ipc_msg_data, + .ipc_pcm_params = intel_ipc_pcm_params, + /* debug */ .debug_map = byt_debugfs, .debug_map_count = ARRAY_SIZE(byt_debugfs), .dbg_dump = byt_dump, + /* stream callbacks */ + .pcm_open = intel_pcm_open, + .pcm_close = intel_pcm_close, + /* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -772,11 +779,18 @@ const struct snd_sof_dsp_ops sof_byt_ops = { .send_msg = byt_send_msg, .fw_ready = byt_fw_ready, + .ipc_msg_data = intel_ipc_msg_data, + .ipc_pcm_params = intel_ipc_pcm_params, + /* debug */ .debug_map = byt_debugfs, .debug_map_count = ARRAY_SIZE(byt_debugfs), .dbg_dump = byt_dump, + /* stream callbacks */ + .pcm_open = intel_pcm_open, + .pcm_close = intel_pcm_close, + /* module loading */ .load_module = snd_sof_parse_module_memcpy, @@ -826,11 +840,18 @@ const struct snd_sof_dsp_ops sof_cht_ops = { .send_msg = byt_send_msg, .fw_ready = byt_fw_ready, + .ipc_msg_data = intel_ipc_msg_data, + .ipc_pcm_params = intel_ipc_pcm_params, + /* debug */ .debug_map = cht_debugfs, .debug_map_count = ARRAY_SIZE(cht_debugfs), .dbg_dump = byt_dump, + /* stream callbacks */ + .pcm_open = intel_pcm_open, + .pcm_close = intel_pcm_close, + /* module loading */ .load_module = snd_sof_parse_module_memcpy, diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index d5866585c637c1..9ac2e0ebb83400 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -190,6 +190,9 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .send_msg = cnl_ipc_send_msg, .fw_ready = hda_dsp_ipc_fw_ready, + .ipc_msg_data = hda_ipc_msg_data, + .ipc_pcm_params = hda_ipc_pcm_params, + /* debug */ .debug_map = cnl_dsp_debugfs, .debug_map_count = ARRAY_SIZE(cnl_dsp_debugfs), diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index 0be89d1dce3d36..525d508817c776 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -402,3 +402,50 @@ int hda_dsp_ipc_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return 0; } + +void hda_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 hdac_stream *hstream = substream->runtime->private_data; + struct sof_intel_hda_stream *hda_stream; + + hda_stream = container_of(hstream, + struct sof_intel_hda_stream, + hda_stream.hstream); + + /* The stream might already be closed */ + if (hstream) + snd_sof_dsp_mailbox_read(sdev, + hda_stream->stream.posn_offset, + p, sz); + } +} + +int hda_ipc_pcm_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply) +{ + struct hdac_stream *hstream = substream->runtime->private_data; + struct sof_intel_hda_stream *hda_stream; + /* validate offset */ + size_t posn_offset = reply->posn_offset; + + hda_stream = container_of(hstream, struct sof_intel_hda_stream, + hda_stream.hstream); + + /* 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; + + hda_stream->stream.posn_offset = sdev->stream_box.offset + posn_offset; + + dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu", + substream->stream, hda_stream->stream.posn_offset); + + return 0; +} diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index f5f2bc8571ae2b..6290b2df5e621d 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -551,11 +551,15 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) /* create capture streams */ for (i = 0; i < num_capture; i++) { + struct sof_intel_hda_stream *hda_stream; - stream = devm_kzalloc(sdev->dev, sizeof(*stream), GFP_KERNEL); - if (!stream) + hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream), + GFP_KERNEL); + if (!hda_stream) return -ENOMEM; + stream = &hda_stream->hda_stream; + stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i; @@ -600,11 +604,15 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) /* create playback streams */ for (i = num_capture; i < num_total; i++) { + struct sof_intel_hda_stream *hda_stream; - stream = devm_kzalloc(sdev->dev, sizeof(*stream), GFP_KERNEL); - if (!stream) + hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream), + GFP_KERNEL); + if (!hda_stream) return -ENOMEM; + stream = &hda_stream->hda_stream; + /* we always have DSP support */ stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i; @@ -657,6 +665,7 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev) struct hdac_bus *bus = sof_to_bus(sdev); struct hdac_stream *s, *_s; struct hdac_ext_stream *stream; + struct sof_intel_hda_stream *hda_stream; /* free position buffer */ if (bus->posbuf.area) @@ -676,6 +685,8 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev) snd_dma_free_pages(&s->bdl); list_del(&s->list); stream = stream_to_hdac_ext_stream(s); - devm_kfree(sdev->dev, stream); + hda_stream = container_of(stream, struct sof_intel_hda_stream, + hda_stream); + devm_kfree(sdev->dev, hda_stream); } } diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index a11196b9acf858..e49d9c92dd1c8b 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -12,6 +12,7 @@ #define __SOF_INTEL_HDA_H #include +#include #include "shim.h" /* PCI registers */ @@ -360,7 +361,7 @@ struct sof_intel_hda_dev { /* hw config */ const struct sof_intel_dsp_desc *desc; - /*trace */ + /* trace */ struct hdac_ext_stream *dtrace_stream; /* if position update IPC needed */ @@ -386,6 +387,11 @@ static inline struct hda_bus *sof_to_hbus(struct snd_sof_dev *s) return &hda->hbus; } +struct sof_intel_hda_stream { + struct hdac_ext_stream hda_stream; + struct sof_intel_stream stream; +}; + #define bus_to_sof_hda(bus) \ container_of(bus, struct sof_intel_hda_dev, hbus.core) @@ -462,6 +468,13 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream, int enable, u32 size); +void hda_ipc_msg_data(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + void *p, size_t sz); +int hda_ipc_pcm_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply); + /* * DSP IPC Operations. */ diff --git a/sound/soc/sof/intel/intel-ipc.c b/sound/soc/sof/intel/intel-ipc.c new file mode 100644 index 00000000000000..675be109920c2d --- /dev/null +++ b/sound/soc/sof/intel/intel-ipc.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: (GPL-2.0 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 */ +void 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) { + snd_sof_dsp_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) + snd_sof_dsp_mailbox_read(sdev, stream->posn_offset, + p, sz); + } +} +EXPORT_SYMBOL(intel_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) +{ + 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(intel_ipc_pcm_params); + +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; + + return 0; +} +EXPORT_SYMBOL(intel_pcm_open); + +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(intel_pcm_close); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h index 617da2dda17270..11fd77cb4e6d0b 100644 --- a/sound/soc/sof/intel/shim.h +++ b/sound/soc/sof/intel/shim.h @@ -176,4 +176,8 @@ extern const struct sof_intel_dsp_desc bdw_chip_info; extern const struct sof_intel_dsp_desc hsw_chip_info; extern const struct sof_intel_dsp_desc tng_chip_info; +struct sof_intel_stream { + size_t posn_offset; +}; + #endif diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index fc998d244b54b8..512c6f0b3deea3 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -343,7 +343,7 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev) int err = 0; /* read back header */ - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &hdr, sizeof(hdr)); + snd_sof_ipc_msg_data(sdev, NULL, &hdr, sizeof(hdr)); ipc_log_header(sdev->dev, "ipc rx", hdr.cmd); cmd = hdr.cmd & SOF_GLB_TYPE_MASK; @@ -406,8 +406,7 @@ static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_id) switch (msg_id) { case SOF_IPC_TRACE_DMA_POSITION: /* read back full message */ - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &posn, - sizeof(posn)); + snd_sof_ipc_msg_data(sdev, NULL, &posn, sizeof(posn)); snd_sof_trace_update_pos(sdev, &posn); break; default: @@ -423,9 +422,9 @@ static void ipc_trace_message(struct snd_sof_dev *sdev, u32 msg_id) static void ipc_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id) { + struct snd_sof_pcm_stream *stream; struct sof_ipc_stream_posn posn; struct snd_sof_pcm *spcm; - u32 posn_offset; int direction; spcm = snd_sof_find_spcm_comp(sdev, msg_id, &direction); @@ -436,33 +435,25 @@ static void ipc_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id) return; } - if (sdev->stream_box.size != 0) { - /* have stream box read from stream box */ - posn_offset = spcm->posn_offset[direction]; - snd_sof_dsp_mailbox_read(sdev, posn_offset, &posn, - sizeof(posn)); - } else { - /* read back full message */ - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &posn, - sizeof(posn)); - } + stream = &spcm->stream[direction]; + snd_sof_ipc_msg_data(sdev, stream->substream, &posn, sizeof(posn)); dev_dbg(sdev->dev, "posn : host 0x%llx dai 0x%llx wall 0x%llx\n", posn.host_posn, posn.dai_posn, posn.wallclock); - memcpy(&spcm->stream[direction].posn, &posn, sizeof(posn)); + memcpy(&stream->posn, &posn, sizeof(posn)); /* only inform ALSA for period_wakeup mode */ - if (!spcm->stream[direction].substream->runtime->no_period_wakeup) - snd_pcm_period_elapsed(spcm->stream[direction].substream); + if (!stream->substream->runtime->no_period_wakeup) + snd_pcm_period_elapsed(stream->substream); } /* DSP notifies host of an XRUN within FW */ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id) { + struct snd_sof_pcm_stream *stream; struct sof_ipc_stream_posn posn; struct snd_sof_pcm *spcm; - u32 posn_offset; int direction; spcm = snd_sof_find_spcm_comp(sdev, msg_id, &direction); @@ -472,24 +463,16 @@ static void ipc_xrun(struct snd_sof_dev *sdev, u32 msg_id) return; } - if (sdev->stream_box.size != 0) { - /* have stream box read from stream box */ - posn_offset = spcm->posn_offset[direction]; - snd_sof_dsp_mailbox_read(sdev, posn_offset, &posn, - sizeof(posn)); - } else { - /* read back full message */ - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, &posn, - sizeof(posn)); - } + stream = &spcm->stream[direction]; + snd_sof_ipc_msg_data(sdev, stream->substream, &posn, sizeof(posn)); dev_dbg(sdev->dev, "posn XRUN: host %llx comp %d size %d\n", posn.host_posn, posn.xrun_comp_id, posn.xrun_size); #if defined(CONFIG_SND_SOC_SOF_DEBUG_XRUN_STOP) /* stop PCM on XRUN - used for pipeline debug */ - memcpy(&spcm->stream[direction].posn, &posn, sizeof(posn)); - snd_pcm_stop_xrun(spcm->stream[direction].substream); + memcpy(&stream->posn, &posn, sizeof(posn)); + snd_pcm_stop_xrun(stream->substream); #endif } diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 8633b587325f4a..f0af78c834fcc8 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -330,6 +330,28 @@ snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev, return 0; } +/* host DSP message data */ +static inline void snd_sof_ipc_msg_data(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + void *p, size_t sz) +{ + if (sof_ops(sdev) && sof_ops(sdev)->ipc_msg_data) + sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz); +} + +/* host configure DSP HW parameters */ +static inline int +snd_sof_ipc_pcm_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply) +{ + if (sof_ops(sdev) && sof_ops(sdev)->ipc_pcm_params) + return sof_ops(sdev)->ipc_pcm_params(sdev, substream, reply); + + dev_err(sdev->dev, "error: %s not defined\n", __func__); + return -ENOTSUPP; +} + /* host stream pointer */ static inline snd_pcm_uframes_t snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev, diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 485dfb92ad5dc1..c81ac2e690b82c 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -38,6 +38,20 @@ static int create_page_table(struct snd_pcm_substream *substream, spcm->stream[stream].page_table.area, size); } +static int sof_pcm_dsp_params(struct snd_sof_pcm *spcm, struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply) +{ + struct snd_sof_dev *sdev = spcm->sdev; + /* validate offset */ + int ret = snd_sof_ipc_pcm_params(sdev, substream, reply); + + if (ret < 0) + dev_err(sdev->dev, "error: got wrong reply for PCM %d\n", + spcm->pcm.pcm_id); + + return ret; +} + /* this may get called several times by oss emulation */ static int sof_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -50,7 +64,6 @@ static int sof_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_sof_pcm *spcm; struct sof_ipc_pcm_params pcm; struct sof_ipc_pcm_params_reply ipc_params_reply; - int posn_offset; int ret; /* nothing todo for BE */ @@ -149,21 +162,9 @@ static int sof_pcm_hw_params(struct snd_pcm_substream *substream, return ret; } - /* validate offset */ - posn_offset = ipc_params_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) { - dev_err(sdev->dev, "error: got wrong posn offset 0x%x for PCM %d\n", - posn_offset, spcm->pcm.pcm_id); - return -EINVAL; - } - spcm->posn_offset[substream->stream] = - sdev->stream_box.offset + posn_offset; - - dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is 0x%x", - substream->stream, spcm->posn_offset[substream->stream]); + ret = sof_pcm_dsp_params(spcm, substream, &ipc_params_reply); + if (ret < 0) + return ret; /* save pcm hw_params */ memcpy(&spcm->params[substream->stream], params, sizeof(*params)); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index a5d8573ccd7361..468fa942655b31 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -148,6 +148,16 @@ struct snd_sof_dsp_ops { snd_pcm_uframes_t (*pcm_pointer)(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); /* optional */ + /* host read DSP stream data */ + void (*ipc_msg_data)(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + void *p, size_t sz); /* mandatory */ + + /* host configure DSP HW parameters */ + int (*ipc_pcm_params)(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply); /* mandatory */ + /* pre/post firmware run */ int (*pre_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ @@ -273,7 +283,6 @@ struct snd_sof_pcm { struct snd_sof_dev *sdev; struct snd_soc_tplg_pcm pcm; struct snd_sof_pcm_stream stream[2]; - u32 posn_offset[2]; struct list_head list; /* list in sdev pcm list */ struct snd_pcm_hw_params params[2]; int restore_stream[2]; /* restore hw_params for paused stream */ @@ -610,4 +619,16 @@ void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, size_t size); +void intel_ipc_msg_data(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); + #endif From e92feaa58eadd0b3e607dbb165ea3b017bfa522e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Apr 2019 16:37:57 +0200 Subject: [PATCH 04/11] ASoC: SOF: skl: remove direct mailbox reading from SOF core Obtaining data from the DSP by reading the mailbox is Intel-specific, move them from the SOF core to Intel-specific drivers. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/skl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index 5aab147dbde6bb..413613e44a3053 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -52,6 +52,9 @@ const struct snd_sof_dsp_ops sof_skl_ops = { .send_msg = hda_dsp_ipc_send_msg, .fw_ready = hda_dsp_ipc_fw_ready, + .ipc_msg_data = hda_ipc_msg_data, + .ipc_pcm_params = hda_ipc_pcm_params, + /* debug */ .debug_map = skl_dsp_debugfs, .debug_map_count = ARRAY_SIZE(skl_dsp_debugfs), From f0ed8591944db7b1739c89978a0689db59ba2887 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Apr 2019 16:42:35 +0200 Subject: [PATCH 05/11] ASoC: SOF: hsw: remove direct mailbox reading from SOF core Obtaining data from the DSP by reading the mailbox is Intel-specific, move them from the SOF core to Intel-specific drivers. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/Kconfig | 1 + sound/soc/sof/intel/hsw.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index 9deb126f5d15a2..c20f2d3164498b 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -83,6 +83,7 @@ config SND_SOC_SOF_HASWELL_SUPPORT config SND_SOC_SOF_HASWELL tristate select SND_SOC_SOF_INTEL_COMMON + select SND_SOC_SOF_INTEL_HIFI_EP_IPC help This option is not user-selectable but automagically handled by 'select' statements at a higher level diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index ee921ab5360b4b..4b802a5a8ed0b0 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -674,11 +674,18 @@ const struct snd_sof_dsp_ops sof_hsw_ops = { .send_msg = hsw_send_msg, .fw_ready = hsw_fw_ready, + .ipc_msg_data = intel_ipc_msg_data, + .ipc_pcm_params = intel_ipc_pcm_params, + /* debug */ .debug_map = hsw_debugfs, .debug_map_count = ARRAY_SIZE(hsw_debugfs), .dbg_dump = hsw_dump, + /* stream callbacks */ + .pcm_open = intel_pcm_open, + .pcm_close = intel_pcm_close, + /* Module loading */ .load_module = snd_sof_parse_module_memcpy, From 6af46a48fc31773d4bf42ae3bcd510d65234a54f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Apr 2019 17:13:02 +0200 Subject: [PATCH 06/11] ASoC: SOF: remove .mailbox_{read,write}() operations IPC implementation using mailboxes is hardware-specific, no need to export it globally. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/apl.c | 4 ---- sound/soc/sof/intel/bdw.c | 4 ---- sound/soc/sof/intel/byt.c | 12 ------------ sound/soc/sof/intel/cnl.c | 4 ---- sound/soc/sof/intel/hda-ipc.c | 7 +++---- sound/soc/sof/intel/intel-ipc.c | 5 ++--- sound/soc/sof/ops.h | 25 ------------------------- sound/soc/sof/sof-priv.h | 6 ------ 8 files changed, 5 insertions(+), 62 deletions(-) diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 2fe7fe2ac55369..8c628260694467 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -44,10 +44,6 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .irq_handler = hda_dsp_ipc_irq_handler, .irq_thread = hda_dsp_ipc_irq_thread, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = hda_dsp_ipc_send_msg, .fw_ready = hda_dsp_ipc_fw_ready, diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 5210dd77cced15..fe357e7881ff52 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -666,10 +666,6 @@ const struct snd_sof_dsp_ops sof_bdw_ops = { .block_read = sof_block_read, .block_write = sof_block_write, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = bdw_send_msg, .fw_ready = bdw_fw_ready, diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 0bd2a3c38df8fd..8428e28bdab214 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -605,10 +605,6 @@ const struct snd_sof_dsp_ops sof_tng_ops = { .irq_handler = byt_irq_handler, .irq_thread = byt_irq_thread, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = byt_send_msg, .fw_ready = byt_fw_ready, @@ -771,10 +767,6 @@ const struct snd_sof_dsp_ops sof_byt_ops = { .irq_handler = byt_irq_handler, .irq_thread = byt_irq_thread, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = byt_send_msg, .fw_ready = byt_fw_ready, @@ -832,10 +824,6 @@ const struct snd_sof_dsp_ops sof_cht_ops = { .irq_handler = byt_irq_handler, .irq_thread = byt_irq_thread, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = byt_send_msg, .fw_ready = byt_fw_ready, diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 9ac2e0ebb83400..3e95c1e5e49120 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -182,10 +182,6 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .irq_handler = hda_dsp_ipc_irq_handler, .irq_thread = cnl_ipc_irq_thread, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = cnl_ipc_send_msg, .fw_ready = hda_dsp_ipc_fw_ready, diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index 525d508817c776..d691d3486ae12c 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -408,7 +408,7 @@ void hda_ipc_msg_data(struct snd_sof_dev *sdev, void *p, size_t sz) { if (!substream || !sdev->stream_box.size) { - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); + sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); } else { struct hdac_stream *hstream = substream->runtime->private_data; struct sof_intel_hda_stream *hda_stream; @@ -419,9 +419,8 @@ void hda_ipc_msg_data(struct snd_sof_dev *sdev, /* The stream might already be closed */ if (hstream) - snd_sof_dsp_mailbox_read(sdev, - hda_stream->stream.posn_offset, - p, sz); + sof_mailbox_read(sdev, hda_stream->stream.posn_offset, + p, sz); } } diff --git a/sound/soc/sof/intel/intel-ipc.c b/sound/soc/sof/intel/intel-ipc.c index 675be109920c2d..4edd92151fd5fb 100644 --- a/sound/soc/sof/intel/intel-ipc.c +++ b/sound/soc/sof/intel/intel-ipc.c @@ -30,14 +30,13 @@ void intel_ipc_msg_data(struct snd_sof_dev *sdev, void *p, size_t sz) { if (!substream || !sdev->stream_box.size) { - snd_sof_dsp_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); + 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) - snd_sof_dsp_mailbox_read(sdev, stream->posn_offset, - p, sz); + sof_mailbox_read(sdev, stream->posn_offset, p, sz); } } EXPORT_SYMBOL(intel_ipc_msg_data); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index f0af78c834fcc8..e209ef86a27934 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -221,31 +221,6 @@ static inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 bar, dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); } -/* mailbox */ -static inline void snd_sof_dsp_mailbox_read(struct snd_sof_dev *sdev, - u32 offset, void *message, - size_t bytes) -{ - if (sof_ops(sdev)->mailbox_read) { - sof_ops(sdev)->mailbox_read(sdev, offset, message, bytes); - return; - } - - dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); -} - -static inline void snd_sof_dsp_mailbox_write(struct snd_sof_dev *sdev, - u32 offset, void *message, - size_t bytes) -{ - if (sof_ops(sdev)->mailbox_write) { - sof_ops(sdev)->mailbox_write(sdev, offset, message, bytes); - return; - } - - dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); -} - /* 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 468fa942655b31..49bc445d22c7e1 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -106,12 +106,6 @@ struct snd_sof_dsp_ops { irqreturn_t (*irq_handler)(int irq, void *context); /* mandatory */ irqreturn_t (*irq_thread)(int irq, void *context); /* mandatory */ - /* mailbox */ - void (*mailbox_read)(struct snd_sof_dev *sof_dev, u32 offset, - void *addr, size_t bytes); /* mandatory */ - void (*mailbox_write)(struct snd_sof_dev *sof_dev, u32 offset, - void *addr, size_t bytes); /* mandatory */ - /* ipc */ int (*send_msg)(struct snd_sof_dev *sof_dev, struct snd_sof_ipc_msg *msg); /* mandatory */ From 36b683031ecdb32eb49ca4330e748e58e64c29cd Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Apr 2019 17:19:59 +0200 Subject: [PATCH 07/11] ASoC: SOF: spi: remove .mailbox_{read,write}() operations IPC implementation using mailboxes is hardware-specific and it is meaningless on serial busses like SPI. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/hw-spi.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/sof/hw-spi.c b/sound/soc/sof/hw-spi.c index 883f53767294b5..42a837fdc859b3 100644 --- a/sound/soc/sof/hw-spi.c +++ b/sound/soc/sof/hw-spi.c @@ -280,10 +280,6 @@ const struct snd_sof_dsp_ops snd_sof_spi_ops = { .irq_handler = spi_irq_handler, .irq_thread = spi_irq_thread, - /* mailbox */ - .mailbox_read = spi_mailbox_read, - .mailbox_write = spi_mailbox_write, - /* ipc */ .send_msg = spi_send_msg, .fw_ready = spi_fw_ready, From 734eba39455034469bb0094c5f8851427b791594 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Apr 2019 17:21:53 +0200 Subject: [PATCH 08/11] ASoC: SOF: hsw: remove .mailbox_{read,write}() operations IPC implementation using mailboxes is hardware-specific, no need to export it globally. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/hsw.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index 4b802a5a8ed0b0..55e430c73ae11e 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -666,10 +666,6 @@ const struct snd_sof_dsp_ops sof_hsw_ops = { .block_read = sof_block_read, .block_write = sof_block_write, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = hsw_send_msg, .fw_ready = hsw_fw_ready, From cfee6b7f037db4a8586242dfbf87b4cd1214baca Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Apr 2019 17:22:09 +0200 Subject: [PATCH 09/11] ASoC: SOF: skl: remove .mailbox_{read,write}() operations IPC implementation using mailboxes is hardware-specific, no need to export it globally. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/skl.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index 413613e44a3053..34f7aa93c86597 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -44,10 +44,6 @@ const struct snd_sof_dsp_ops sof_skl_ops = { .irq_handler = hda_dsp_ipc_irq_handler, .irq_thread = hda_dsp_ipc_irq_thread, - /* mailbox */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - /* ipc */ .send_msg = hda_dsp_ipc_send_msg, .fw_ready = hda_dsp_ipc_fw_ready, From 71f992cf18c45ea1224a8074eefe36e6f3362d94 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 2 Apr 2019 16:57:43 +0200 Subject: [PATCH 10/11] ASoC: SOF: IPC: remove a superfluous function argument snd_sof_fw_parse_ext_data() is always called for the MMIO BAR, remove the argument and specify the BAR explicitly. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/intel/bdw.c | 2 +- sound/soc/sof/intel/byt.c | 2 +- sound/soc/sof/intel/hda-ipc.c | 3 +-- sound/soc/sof/intel/hsw.c | 2 +- sound/soc/sof/loader.c | 8 ++++---- sound/soc/sof/sof-priv.h | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index fe357e7881ff52..4c17cb347ffd7d 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -459,7 +459,7 @@ static int bdw_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return ret; /* now check for extended data */ - snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, MBOX_OFFSET + + snd_sof_fw_parse_ext_data(sdev, MBOX_OFFSET + sizeof(struct sof_ipc_fw_ready)); bdw_get_windows(sdev); diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 8428e28bdab214..b4a71ba18dbc9e 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -248,7 +248,7 @@ static int byt_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return ret; /* now check for extended data */ - snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, MBOX_OFFSET + + snd_sof_fw_parse_ext_data(sdev, MBOX_OFFSET + sizeof(struct sof_ipc_fw_ready)); byt_get_windows(sdev); diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index d691d3486ae12c..7fbd1cca6240b9 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -394,8 +394,7 @@ int hda_dsp_ipc_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return ret; /* now check for extended data */ - snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, - HDA_DSP_MBOX_UPLINK_OFFSET + + snd_sof_fw_parse_ext_data(sdev, HDA_DSP_MBOX_UPLINK_OFFSET + sizeof(struct sof_ipc_fw_ready)); ipc_get_windows(sdev); diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index 55e430c73ae11e..2b4a44fa6f3912 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -460,7 +460,7 @@ static int hsw_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return ret; /* now check for extended data */ - snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, MBOX_OFFSET + + snd_sof_fw_parse_ext_data(sdev, MBOX_OFFSET + sizeof(struct sof_ipc_fw_ready)); hsw_get_windows(sdev); diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index dafa4dec196125..72445f10e7b672 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -35,7 +35,7 @@ static int get_ext_windows(struct snd_sof_dev *sdev, } /* parse the extended FW boot data structures from FW boot message */ -int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset) +int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 offset) { struct sof_ipc_ext_data_hdr *ext_hdr; void *ext_data; @@ -46,14 +46,14 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset) return -ENOMEM; /* get first header */ - snd_sof_dsp_block_read(sdev, bar, offset, ext_data, + snd_sof_dsp_block_read(sdev, sdev->mmio_bar, offset, ext_data, sizeof(*ext_hdr)); ext_hdr = ext_data; while (ext_hdr->hdr.cmd == SOF_IPC_FW_READY) { /* read in ext structure */ offset += sizeof(*ext_hdr); - snd_sof_dsp_block_read(sdev, bar, offset, + snd_sof_dsp_block_read(sdev, sdev->mmio_bar, offset, (void *)((u8 *)ext_data + sizeof(*ext_hdr)), ext_hdr->hdr.size - sizeof(*ext_hdr)); @@ -79,7 +79,7 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset) /* move to next header */ offset += ext_hdr->hdr.size; - snd_sof_dsp_block_read(sdev, bar, offset, ext_data, + snd_sof_dsp_block_read(sdev, sdev->mmio_bar, offset, ext_data, sizeof(*ext_hdr)); ext_hdr = ext_data; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 49bc445d22c7e1..876d128e16237b 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -444,7 +444,7 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev); int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, struct snd_sof_mod_hdr *module); void snd_sof_fw_unload(struct snd_sof_dev *sdev); -int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset); +int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 offset); /* * IPC low level APIs. From e044b43d549a9360f5e00ed08caa3589c1055b32 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 2 Apr 2019 17:29:38 +0200 Subject: [PATCH 11/11] ASoC: SOF: IPC: remove a superfluous argument from functions .block_read() and .block_write() operations as well as their respective implementations sof_block_read() and sof_block_write() are always used with the MMIO BAR. Remove the argument and specify the BAR explicitly. Signed-off-by: Guennadi Liakhovetski --- sound/soc/sof/hw-spi.c | 4 ++-- sound/soc/sof/intel/bdw.c | 3 +-- sound/soc/sof/intel/byt.c | 3 +-- sound/soc/sof/intel/hda-ipc.c | 3 +-- sound/soc/sof/intel/hda.c | 6 +++--- sound/soc/sof/intel/hsw.c | 3 +-- sound/soc/sof/ipc.c | 4 ++-- sound/soc/sof/loader.c | 9 ++++----- sound/soc/sof/ops.h | 8 ++++---- sound/soc/sof/sof-priv.h | 8 ++++---- sound/soc/sof/utils.c | 8 ++++---- 11 files changed, 27 insertions(+), 32 deletions(-) diff --git a/sound/soc/sof/hw-spi.c b/sound/soc/sof/hw-spi.c index 42a837fdc859b3..144098ced14b3a 100644 --- a/sound/soc/sof/hw-spi.c +++ b/sound/soc/sof/hw-spi.c @@ -36,7 +36,7 @@ * Memory copy. */ -static void spi_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, +static void spi_block_read(struct snd_sof_dev *sdev, u32 offset, void *dest, size_t size) { u8 *buf; @@ -62,7 +62,7 @@ static void spi_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, } } -static void spi_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, +static void spi_block_write(struct snd_sof_dev *sdev, u32 offset, void *src, size_t size) { int ret; diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 4c17cb347ffd7d..da11a2f1240ebb 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -445,8 +445,7 @@ static int bdw_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return 0; /* copy data from the DSP FW ready offset */ - sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready, - sizeof(*fw_ready)); + sof_block_read(sdev, offset, fw_ready, sizeof(*fw_ready)); snd_sof_dsp_mailbox_init(sdev, fw_ready->dspbox_offset, fw_ready->dspbox_size, diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index b4a71ba18dbc9e..b2e01f628356f6 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -234,8 +234,7 @@ static int byt_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return 0; /* copy data from the DSP FW ready offset */ - sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready, - sizeof(*fw_ready)); + sof_block_read(sdev, offset, fw_ready, sizeof(*fw_ready)); snd_sof_dsp_mailbox_init(sdev, fw_ready->dspbox_offset, fw_ready->dspbox_size, diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index 7fbd1cca6240b9..009d0d95f92b3e 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -385,8 +385,7 @@ int hda_dsp_ipc_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return 0; /* copy data from the DSP FW ready offset */ - sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready, - sizeof(*fw_ready)); + sof_block_read(sdev, offset, fw_ready, sizeof(*fw_ready)); /* make sure ABI version is compatible */ ret = snd_sof_ipc_valid(sdev); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index b8fc19790f3b80..b5694dba1b5089 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -109,15 +109,15 @@ static void hda_dsp_get_registers(struct snd_sof_dev *sdev, u32 *stack, size_t stack_words) { /* first read registers */ - sof_block_read(sdev, sdev->mmio_bar, sdev->dsp_oops_offset, xoops, + sof_block_read(sdev, sdev->dsp_oops_offset, xoops, sizeof(*xoops)); /* then get panic info */ - sof_block_read(sdev, sdev->mmio_bar, sdev->dsp_oops_offset + + sof_block_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops), panic_info, sizeof(*panic_info)); /* then get the stack */ - sof_block_read(sdev, sdev->mmio_bar, sdev->dsp_oops_offset + + sof_block_read(sdev, sdev->dsp_oops_offset + sizeof(*xoops) + sizeof(*panic_info), stack, stack_words * sizeof(u32)); } diff --git a/sound/soc/sof/intel/hsw.c b/sound/soc/sof/intel/hsw.c index 2b4a44fa6f3912..950b5617ff27ea 100644 --- a/sound/soc/sof/intel/hsw.c +++ b/sound/soc/sof/intel/hsw.c @@ -446,8 +446,7 @@ static int hsw_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return 0; /* copy data from the DSP FW ready offset */ - sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready, - sizeof(*fw_ready)); + sof_block_read(sdev, offset, fw_ready, sizeof(*fw_ready)); snd_sof_dsp_mailbox_init(sdev, fw_ready->dspbox_offset, fw_ready->dspbox_size, diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 512c6f0b3deea3..f1d95f232789a9 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -645,12 +645,12 @@ int snd_sof_ipc_set_get_comp_data(struct snd_sof_ipc *ipc, send_bytes = sizeof(struct sof_ipc_ctrl_value_chan) * cdata->num_elems; if (send) - snd_sof_dsp_block_write(sdev, sdev->mmio_bar, + snd_sof_dsp_block_write(sdev, scontrol->readback_offset, cdata->chanv, send_bytes); else - snd_sof_dsp_block_read(sdev, sdev->mmio_bar, + snd_sof_dsp_block_read(sdev, scontrol->readback_offset, cdata->chanv, send_bytes); return 0; diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index 72445f10e7b672..b46fe778185465 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -46,14 +46,14 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 offset) return -ENOMEM; /* get first header */ - snd_sof_dsp_block_read(sdev, sdev->mmio_bar, offset, ext_data, + snd_sof_dsp_block_read(sdev, offset, ext_data, sizeof(*ext_hdr)); ext_hdr = ext_data; while (ext_hdr->hdr.cmd == SOF_IPC_FW_READY) { /* read in ext structure */ offset += sizeof(*ext_hdr); - snd_sof_dsp_block_read(sdev, sdev->mmio_bar, offset, + snd_sof_dsp_block_read(sdev, offset, (void *)((u8 *)ext_data + sizeof(*ext_hdr)), ext_hdr->hdr.size - sizeof(*ext_hdr)); @@ -79,7 +79,7 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 offset) /* move to next header */ offset += ext_hdr->hdr.size; - snd_sof_dsp_block_read(sdev, sdev->mmio_bar, offset, ext_data, + snd_sof_dsp_block_read(sdev, offset, ext_data, sizeof(*ext_hdr)); ext_hdr = ext_data; } @@ -145,8 +145,7 @@ int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, block->size); return -EINVAL; } - snd_sof_dsp_block_write(sdev, sdev->mmio_bar, offset, - block + 1, block->size); + snd_sof_dsp_block_write(sdev, offset, block + 1, block->size); /* minus body size of block */ remaining -= block->size; diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index e209ef86a27934..34378272e4211d 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -199,22 +199,22 @@ static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar, } /* block IO */ -static inline void snd_sof_dsp_block_read(struct snd_sof_dev *sdev, u32 bar, +static inline void snd_sof_dsp_block_read(struct snd_sof_dev *sdev, u32 offset, void *dest, size_t bytes) { if (sof_ops(sdev)->block_read) { - sof_ops(sdev)->block_read(sdev, bar, offset, dest, bytes); + sof_ops(sdev)->block_read(sdev, offset, dest, bytes); return; } dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); } -static inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 bar, +static inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 offset, void *src, size_t bytes) { if (sof_ops(sdev)->block_write) { - sof_ops(sdev)->block_write(sdev, bar, offset, src, bytes); + sof_ops(sdev)->block_write(sdev, offset, src, bytes); return; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 876d128e16237b..eeb08c44b02370 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -95,10 +95,10 @@ struct snd_sof_dsp_ops { void __iomem *addr); /* mandatory */ /* memcpy IO */ - void (*block_read)(struct snd_sof_dev *sof_dev, u32 bar, + void (*block_read)(struct snd_sof_dev *sof_dev, u32 offset, void *dest, size_t size); /* mandatory */ - void (*block_write)(struct snd_sof_dev *sof_dev, u32 bar, + void (*block_write)(struct snd_sof_dev *sof_dev, u32 offset, void *src, size_t size); /* mandatory */ @@ -608,9 +608,9 @@ void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset, void *message, size_t bytes); void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset, void *message, size_t bytes); -void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, +void sof_block_write(struct snd_sof_dev *sdev, u32 offset, void *src, size_t size); -void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, +void sof_block_read(struct snd_sof_dev *sdev, u32 offset, void *dest, size_t size); void intel_ipc_msg_data(struct snd_sof_dev *sdev, diff --git a/sound/soc/sof/utils.c b/sound/soc/sof/utils.c index 2ac4c3da03206d..b92d713e15887e 100644 --- a/sound/soc/sof/utils.c +++ b/sound/soc/sof/utils.c @@ -71,10 +71,10 @@ EXPORT_SYMBOL(sof_mailbox_read); * Memory copy. */ -void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, +void sof_block_write(struct snd_sof_dev *sdev, u32 offset, void *src, size_t size) { - void __iomem *dest = sdev->bar[bar] + offset; + void __iomem *dest = sdev->bar[sdev->mmio_bar] + offset; const u8 *src_byte = src; u32 affected_mask; u32 tmp; @@ -102,10 +102,10 @@ void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, } EXPORT_SYMBOL(sof_block_write); -void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, +void sof_block_read(struct snd_sof_dev *sdev, u32 offset, void *dest, size_t size) { - void __iomem *src = sdev->bar[bar] + offset; + void __iomem *src = sdev->bar[sdev->mmio_bar] + offset; memcpy_fromio(dest, src, size); }