summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof
diff options
context:
space:
mode:
authorDaniel Baluta <daniel.baluta@nxp.com>2019-08-07 10:02:01 -0500
committerMark Brown <broonie@kernel.org>2019-08-09 13:26:20 +0100
commit83ee7ab1627b7597bbb9acc26b37e9f96fff40c9 (patch)
treee59fc8ffa0bdef3cd195dbe335993f60242aebca /sound/soc/sof
parente17422cda9d60339d71e117d3fdfd444e83669a4 (diff)
downloadlinux-83ee7ab1627b7597bbb9acc26b37e9f96fff40c9.tar.bz2
ASoC: SOF: Intel: byt: Refactor fw ready / mem windows creation
There is a lot of duplicate code when processing IPC firmware ready notification and creating memory windows. First step in reducing the code duplication is to introduce generic functions: * sof_get_windows * sof_fw_ready that will replace, in the first step, the specific implementation related to baytrail related platforms: * byt_get_windows * byt_fw_ready So we are basically moving code from intel/byt.c to loader.c keeping in mind that mbox_offset is a per platform constant so we need to use newly introduced snd_sof_dsp_get_mailbox_offset / snd_sof_dsp_get_window_offset in order to get the correct mbox offset / window offset value. Also, bar is a per platform constant so we use snd_sof_dsp_get_bar_index instead of the hardcoded BYT_DSP_BAR. Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20190807150203.26359-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/intel/byt.c164
-rw-r--r--sound/soc/sof/loader.c168
-rw-r--r--sound/soc/sof/sof-priv.h2
3 files changed, 189 insertions, 145 deletions
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index cb8f02ee09f2..5e7a6aaa627a 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -110,148 +110,6 @@ static void byt_dsp_done(struct snd_sof_dev *sdev);
static void byt_get_reply(struct snd_sof_dev *sdev);
/*
- * IPC Firmware ready.
- */
-static void byt_get_windows(struct snd_sof_dev *sdev)
-{
- struct sof_ipc_window_elem *elem;
- u32 outbox_offset = 0;
- u32 stream_offset = 0;
- u32 inbox_offset = 0;
- u32 outbox_size = 0;
- u32 stream_size = 0;
- u32 inbox_size = 0;
- int i;
-
- if (!sdev->info_window) {
- dev_err(sdev->dev, "error: have no window info\n");
- return;
- }
-
- for (i = 0; i < sdev->info_window->num_windows; i++) {
- elem = &sdev->info_window->window[i];
-
- switch (elem->type) {
- case SOF_IPC_REGION_UPBOX:
- inbox_offset = elem->offset + MBOX_OFFSET;
- inbox_size = elem->size;
- snd_sof_debugfs_io_item(sdev,
- sdev->bar[BYT_DSP_BAR] +
- inbox_offset,
- elem->size, "inbox",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_DOWNBOX:
- outbox_offset = elem->offset + MBOX_OFFSET;
- outbox_size = elem->size;
- snd_sof_debugfs_io_item(sdev,
- sdev->bar[BYT_DSP_BAR] +
- outbox_offset,
- elem->size, "outbox",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_TRACE:
- snd_sof_debugfs_io_item(sdev,
- sdev->bar[BYT_DSP_BAR] +
- elem->offset +
- MBOX_OFFSET,
- elem->size, "etrace",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_DEBUG:
- snd_sof_debugfs_io_item(sdev,
- sdev->bar[BYT_DSP_BAR] +
- elem->offset +
- MBOX_OFFSET,
- elem->size, "debug",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_STREAM:
- stream_offset = elem->offset + MBOX_OFFSET;
- stream_size = elem->size;
- snd_sof_debugfs_io_item(sdev,
- sdev->bar[BYT_DSP_BAR] +
- stream_offset,
- elem->size, "stream",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_REGS:
- snd_sof_debugfs_io_item(sdev,
- sdev->bar[BYT_DSP_BAR] +
- elem->offset +
- MBOX_OFFSET,
- elem->size, "regs",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_EXCEPTION:
- sdev->dsp_oops_offset = elem->offset + MBOX_OFFSET;
- snd_sof_debugfs_io_item(sdev,
- sdev->bar[BYT_DSP_BAR] +
- elem->offset +
- MBOX_OFFSET,
- elem->size, "exception",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- default:
- dev_err(sdev->dev, "error: get illegal window info\n");
- return;
- }
- }
-
- if (outbox_size == 0 || inbox_size == 0) {
- dev_err(sdev->dev, "error: get illegal mailbox window\n");
- return;
- }
-
- snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size,
- outbox_offset, outbox_size);
- sdev->stream_box.offset = stream_offset;
- sdev->stream_box.size = stream_size;
-
- dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
- inbox_offset, inbox_size);
- dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
- outbox_offset, outbox_size);
- dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
- stream_offset, stream_size);
-}
-
-/* check for ABI compatibility and create memory windows on first boot */
-static int byt_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
-{
- struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
- u32 offset;
- int ret;
-
- /* mailbox must be on 4k boundary */
- offset = MBOX_OFFSET;
-
- dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n",
- msg_id, offset);
-
- /* no need to re-check version/ABI for subsequent boots */
- if (!sdev->first_boot)
- return 0;
-
- /* copy data from the DSP FW ready offset */
- sof_block_read(sdev, sdev->mmio_bar, offset, fw_ready,
- sizeof(*fw_ready));
-
- /* make sure ABI version is compatible */
- ret = snd_sof_ipc_valid(sdev);
- if (ret < 0)
- return ret;
-
- /* now check for extended data */
- snd_sof_fw_parse_ext_data(sdev, sdev->mmio_bar, MBOX_OFFSET +
- sizeof(struct sof_ipc_fw_ready));
-
- byt_get_windows(sdev);
-
- return 0;
-}
-
-/*
* Debug
*/
@@ -418,6 +276,16 @@ static void byt_get_reply(struct snd_sof_dev *sdev)
msg->reply_error = ret;
}
+static int byt_get_mailbox_offset(struct snd_sof_dev *sdev)
+{
+ return MBOX_OFFSET;
+}
+
+static int byt_get_window_offset(struct snd_sof_dev *sdev, u32 id)
+{
+ return MBOX_OFFSET;
+}
+
static void byt_host_done(struct snd_sof_dev *sdev)
{
/* clear BUSY bit and set DONE bit - accept new messages */
@@ -612,7 +480,9 @@ const struct snd_sof_dsp_ops sof_tng_ops = {
/* ipc */
.send_msg = byt_send_msg,
- .fw_ready = byt_fw_ready,
+ .fw_ready = sof_fw_ready,
+ .get_mailbox_offset = byt_get_mailbox_offset,
+ .get_window_offset = byt_get_window_offset,
.ipc_msg_data = intel_ipc_msg_data,
.ipc_pcm_params = intel_ipc_pcm_params,
@@ -771,7 +641,9 @@ const struct snd_sof_dsp_ops sof_byt_ops = {
/* ipc */
.send_msg = byt_send_msg,
- .fw_ready = byt_fw_ready,
+ .fw_ready = sof_fw_ready,
+ .get_mailbox_offset = byt_get_mailbox_offset,
+ .get_window_offset = byt_get_window_offset,
.ipc_msg_data = intel_ipc_msg_data,
.ipc_pcm_params = intel_ipc_pcm_params,
@@ -828,7 +700,9 @@ const struct snd_sof_dsp_ops sof_cht_ops = {
/* ipc */
.send_msg = byt_send_msg,
- .fw_ready = byt_fw_ready,
+ .fw_ready = sof_fw_ready,
+ .get_mailbox_offset = byt_get_mailbox_offset,
+ .get_window_offset = byt_get_window_offset,
.ipc_msg_data = intel_ipc_msg_data,
.ipc_pcm_params = intel_ipc_pcm_params,
diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c
index 93cb8fd0844f..d7f32745fefe 100644
--- a/sound/soc/sof/loader.c
+++ b/sound/soc/sof/loader.c
@@ -87,6 +87,174 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset)
}
EXPORT_SYMBOL(snd_sof_fw_parse_ext_data);
+/*
+ * IPC Firmware ready.
+ */
+static void sof_get_windows(struct snd_sof_dev *sdev)
+{
+ struct sof_ipc_window_elem *elem;
+ u32 outbox_offset = 0;
+ u32 stream_offset = 0;
+ u32 inbox_offset = 0;
+ u32 outbox_size = 0;
+ u32 stream_size = 0;
+ u32 inbox_size = 0;
+ int window_offset;
+ int bar;
+ int i;
+
+ if (!sdev->info_window) {
+ dev_err(sdev->dev, "error: have no window info\n");
+ return;
+ }
+
+ bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM);
+ if (bar < 0) {
+ dev_err(sdev->dev, "error: have no bar mapping\n");
+ return;
+ }
+
+ for (i = 0; i < sdev->info_window->num_windows; i++) {
+ elem = &sdev->info_window->window[i];
+
+ window_offset = snd_sof_dsp_get_window_offset(sdev, elem->id);
+ if (window_offset < 0) {
+ dev_warn(sdev->dev, "warn: no offset for window %d\n",
+ elem->id);
+ continue;
+ }
+
+ switch (elem->type) {
+ case SOF_IPC_REGION_UPBOX:
+ inbox_offset = window_offset + elem->offset;
+ inbox_size = elem->size;
+ snd_sof_debugfs_io_item(sdev,
+ sdev->bar[bar] +
+ inbox_offset,
+ elem->size, "inbox",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_DOWNBOX:
+ outbox_offset = window_offset + elem->offset;
+ outbox_size = elem->size;
+ snd_sof_debugfs_io_item(sdev,
+ sdev->bar[bar] +
+ outbox_offset,
+ elem->size, "outbox",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_TRACE:
+ snd_sof_debugfs_io_item(sdev,
+ sdev->bar[bar] +
+ window_offset +
+ elem->offset,
+ elem->size, "etrace",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_DEBUG:
+ snd_sof_debugfs_io_item(sdev,
+ sdev->bar[bar] +
+ window_offset +
+ elem->offset,
+ elem->size, "debug",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_STREAM:
+ stream_offset = window_offset + elem->offset;
+ stream_size = elem->size;
+ snd_sof_debugfs_io_item(sdev,
+ sdev->bar[bar] +
+ stream_offset,
+ elem->size, "stream",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_REGS:
+ snd_sof_debugfs_io_item(sdev,
+ sdev->bar[bar] +
+ window_offset +
+ elem->offset,
+ elem->size, "regs",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_EXCEPTION:
+ sdev->dsp_oops_offset = window_offset + elem->offset;
+ snd_sof_debugfs_io_item(sdev,
+ sdev->bar[bar] +
+ window_offset +
+ elem->offset,
+ elem->size, "exception",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ default:
+ dev_err(sdev->dev, "error: get illegal window info\n");
+ return;
+ }
+ }
+
+ if (outbox_size == 0 || inbox_size == 0) {
+ dev_err(sdev->dev, "error: get illegal mailbox window\n");
+ return;
+ }
+
+ snd_sof_dsp_mailbox_init(sdev, inbox_offset, inbox_size,
+ outbox_offset, outbox_size);
+ sdev->stream_box.offset = stream_offset;
+ sdev->stream_box.size = stream_size;
+
+ dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
+ inbox_offset, inbox_size);
+ dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
+ outbox_offset, outbox_size);
+ dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
+ stream_offset, stream_size);
+}
+
+/* check for ABI compatibility and create memory windows on first boot */
+int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
+{
+ struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
+ int offset;
+ int bar;
+ int ret;
+
+ /* mailbox must be on 4k boundary */
+ offset = snd_sof_dsp_get_mailbox_offset(sdev);
+ if (offset < 0) {
+ dev_err(sdev->dev, "error: have no mailbox offset\n");
+ return offset;
+ }
+
+ bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM);
+ if (bar < 0) {
+ dev_err(sdev->dev, "error: have no bar mapping\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n",
+ msg_id, offset);
+
+ /* no need to re-check version/ABI for subsequent boots */
+ if (!sdev->first_boot)
+ return 0;
+
+ /* copy data from the DSP FW ready offset */
+ sof_block_read(sdev, bar, offset, fw_ready, sizeof(*fw_ready));
+
+ /* make sure ABI version is compatible */
+ ret = snd_sof_ipc_valid(sdev);
+ if (ret < 0)
+ return ret;
+
+ /* now check for extended data */
+ snd_sof_fw_parse_ext_data(sdev, bar, offset +
+ sizeof(struct sof_ipc_fw_ready));
+
+ sof_get_windows(sdev);
+
+ return 0;
+}
+EXPORT_SYMBOL(sof_fw_ready);
+
/* generic module parser for mmaped DSPs */
int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev,
struct snd_sof_mod_hdr *module)
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index de11f28bae3a..730f3259dd02 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -642,6 +642,8 @@ 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);
+int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id);
+
void intel_ipc_msg_data(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
void *p, size_t sz);