diff options
author | Peter Ujfalusi <peter.ujfalusi@linux.intel.com> | 2021-09-15 15:21:11 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-09-15 16:25:04 +0100 |
commit | 4624bb2f03d3c153e00d21c1baa1da34cfc19afd (patch) | |
tree | 16c33d6968d40b93f5d7ef45bb21caafa26912ba | |
parent | 4ff134e2f90ee2816ca5a8069802ff5cb602a2f1 (diff) | |
download | linux-4624bb2f03d3c153e00d21c1baa1da34cfc19afd.tar.bz2 |
ASoC: SOF: core: Do not use 'bar' as parameter for block_read/write
The use of bar in the core poses limits on the portability of the code
to other, non iomapped platforms.
To make the API more generic, remove the use of 'bar' as parameter
for the block copy API.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Daniel Baluta <daniel.baluta@gmail.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Link: https://lore.kernel.org/r/20210915122116.18317-8-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/sof/ipc.c | 18 | ||||
-rw-r--r-- | sound/soc/sof/loader.c | 62 | ||||
-rw-r--r-- | sound/soc/sof/ops.h | 14 | ||||
-rw-r--r-- | sound/soc/sof/sof-priv.h | 20 | ||||
-rw-r--r-- | sound/soc/sof/utils.c | 28 |
5 files changed, 78 insertions, 64 deletions
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index 9ca3681d266d..18e0bfc1d8a9 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -709,15 +709,19 @@ int snd_sof_ipc_set_get_comp_data(struct snd_sof_control *scontrol, send_bytes = sizeof(struct sof_ipc_ctrl_value_chan) * cdata->num_elems; if (send) - snd_sof_dsp_block_write(sdev, sdev->mmio_bar, - scontrol->readback_offset, - cdata->chanv, send_bytes); + err = snd_sof_dsp_block_write(sdev, SOF_FW_BLK_TYPE_IRAM, + scontrol->readback_offset, + cdata->chanv, send_bytes); else - snd_sof_dsp_block_read(sdev, sdev->mmio_bar, - scontrol->readback_offset, - cdata->chanv, send_bytes); - return 0; + err = snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_IRAM, + scontrol->readback_offset, + cdata->chanv, send_bytes); + + if (err) + dev_err_once(sdev->dev, "error: %s TYPE_IRAM failed\n", + send ? "write to" : "read from"); + return err; } cdata->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | ipc_cmd; diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index cf98aeb1cfdd..c076fc3523b3 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -86,7 +86,7 @@ static int get_cc_info(struct snd_sof_dev *sdev, } /* parse the extended FW boot data structures from FW boot message */ -static int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset) +static 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; @@ -97,15 +97,16 @@ static int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offs return -ENOMEM; /* get first header */ - snd_sof_dsp_block_read(sdev, bar, offset, ext_data, + snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, ext_data, sizeof(*ext_hdr)); ext_hdr = ext_data; while (ext_hdr->hdr.cmd == SOF_IPC_FW_READY) { /* read in ext structure */ - snd_sof_dsp_block_read(sdev, bar, offset + sizeof(*ext_hdr), - (void *)((u8 *)ext_data + sizeof(*ext_hdr)), - ext_hdr->hdr.size - sizeof(*ext_hdr)); + snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, + offset + sizeof(*ext_hdr), + (void *)((u8 *)ext_data + sizeof(*ext_hdr)), + ext_hdr->hdr.size - sizeof(*ext_hdr)); dev_dbg(sdev->dev, "found ext header type %d size 0x%x\n", ext_hdr->type, ext_hdr->hdr.size); @@ -138,7 +139,7 @@ static int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offs /* 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, SOF_FW_BLK_TYPE_SRAM, offset, ext_data, sizeof(*ext_hdr)); ext_hdr = ext_data; } @@ -361,6 +362,7 @@ static int snd_sof_fw_ext_man_parse(struct snd_sof_dev *sdev, */ static void sof_get_windows(struct snd_sof_dev *sdev) { + int bar = snd_sof_dsp_get_bar_index(sdev, SOF_FW_BLK_TYPE_SRAM); struct sof_ipc_window_elem *elem; u32 outbox_offset = 0; u32 stream_offset = 0; @@ -371,7 +373,6 @@ static void sof_get_windows(struct snd_sof_dev *sdev) u32 debug_size = 0; u32 debug_offset = 0; int window_offset; - int bar; int i; if (!sdev->info_window) { @@ -379,12 +380,6 @@ static void sof_get_windows(struct snd_sof_dev *sdev) 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]; @@ -496,7 +491,6 @@ 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 */ @@ -506,12 +500,6 @@ int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) 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); @@ -519,8 +507,17 @@ int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) if (!sdev->first_boot) return 0; - /* copy data from the DSP FW ready offset */ - snd_sof_dsp_block_read(sdev, bar, offset, fw_ready, sizeof(*fw_ready)); + /* + * copy data from the DSP FW ready offset + * Subsequent error handling is not needed for BLK_TYPE_SRAM + */ + ret = snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, fw_ready, + sizeof(*fw_ready)); + if (ret) { + dev_err(sdev->dev, + "error: unable to read fw_ready, read from TYPE_SRAM failed\n"); + return ret; + } /* make sure ABI version is compatible */ ret = snd_sof_ipc_valid(sdev); @@ -528,8 +525,7 @@ int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id) return ret; /* now check for extended data */ - snd_sof_fw_parse_ext_data(sdev, bar, offset + - sizeof(struct sof_ipc_fw_ready)); + snd_sof_fw_parse_ext_data(sdev, offset + sizeof(struct sof_ipc_fw_ready)); sof_get_windows(sdev); @@ -542,7 +538,7 @@ int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, struct snd_sof_mod_hdr *module) { struct snd_sof_blk_hdr *block; - int count, bar; + int count, ret; u32 offset; size_t remaining; @@ -579,13 +575,6 @@ int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, case SOF_FW_BLK_TYPE_DRAM: case SOF_FW_BLK_TYPE_SRAM: offset = block->offset; - bar = snd_sof_dsp_get_bar_index(sdev, block->type); - if (bar < 0) { - dev_err(sdev->dev, - "error: no BAR mapping for block type 0x%x\n", - block->type); - return bar; - } break; default: dev_err(sdev->dev, "error: bad type 0x%x for block 0x%x\n", @@ -603,8 +592,13 @@ int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev, block->size); return -EINVAL; } - snd_sof_dsp_block_write(sdev, bar, offset, - block + 1, block->size); + ret = snd_sof_dsp_block_write(sdev, block->type, offset, + block + 1, block->size); + if (ret < 0) { + dev_err(sdev->dev, "error: write to block type 0x%x failed\n", + block->type); + return ret; + } if (remaining < block->size) { dev_err(sdev->dev, "error: not enough data remaining\n"); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 731b8157aaea..2412b5a77e42 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -297,16 +297,18 @@ 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, - u32 offset, void *dest, size_t bytes) +static inline int snd_sof_dsp_block_read(struct snd_sof_dev *sdev, + enum snd_sof_fw_blk_type blk_type, + u32 offset, void *dest, size_t bytes) { - sof_ops(sdev)->block_read(sdev, bar, offset, dest, bytes); + return sof_ops(sdev)->block_read(sdev, blk_type, offset, dest, bytes); } -static inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 bar, - u32 offset, void *src, size_t bytes) +static inline int snd_sof_dsp_block_write(struct snd_sof_dev *sdev, + enum snd_sof_fw_blk_type blk_type, + u32 offset, void *src, size_t bytes) { - sof_ops(sdev)->block_write(sdev, bar, offset, src, bytes); + return sof_ops(sdev)->block_write(sdev, blk_type, offset, src, bytes); } /* ipc */ diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 22fad9b0ce52..9a05d0c7a7c7 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -127,12 +127,12 @@ struct snd_sof_dsp_ops { void __iomem *addr); /* optional */ /* memcpy IO */ - void (*block_read)(struct snd_sof_dev *sof_dev, u32 bar, - u32 offset, void *dest, - size_t size); /* mandatory */ - void (*block_write)(struct snd_sof_dev *sof_dev, u32 bar, - u32 offset, void *src, - size_t size); /* mandatory */ + int (*block_read)(struct snd_sof_dev *sof_dev, + enum snd_sof_fw_blk_type type, u32 offset, + void *dest, size_t size); /* mandatory */ + int (*block_write)(struct snd_sof_dev *sof_dev, + enum snd_sof_fw_blk_type type, u32 offset, + void *src, size_t size); /* mandatory */ /* doorbell */ irqreturn_t (*irq_handler)(int irq, void *context); /* optional */ @@ -568,10 +568,10 @@ 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, - size_t size); -void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, - size_t size); +int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, + u32 offset, void *src, size_t size); +int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, + u32 offset, void *dest, size_t size); int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id); diff --git a/sound/soc/sof/utils.c b/sound/soc/sof/utils.c index 5539d3afbe8f..66fa6602fb67 100644 --- a/sound/soc/sof/utils.c +++ b/sound/soc/sof/utils.c @@ -14,6 +14,7 @@ #include <sound/soc.h> #include <sound/sof.h> #include "sof-priv.h" +#include "ops.h" /* * Register IO @@ -72,15 +73,21 @@ EXPORT_SYMBOL(sof_mailbox_read); * Memory copy. */ -void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, - size_t size) +int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, + u32 offset, void *src, size_t size) { - void __iomem *dest = sdev->bar[bar] + offset; + int bar = snd_sof_dsp_get_bar_index(sdev, blk_type); const u8 *src_byte = src; + void __iomem *dest; u32 affected_mask; u32 tmp; int m, n; + if (bar < 0) + return bar; + + dest = sdev->bar[bar] + offset; + m = size / 4; n = size % 4; @@ -100,15 +107,22 @@ void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, tmp |= *(u32 *)(src_byte + m * 4) & affected_mask; iowrite32(tmp, dest + m * 4); } + + return 0; } EXPORT_SYMBOL(sof_block_write); -void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, - size_t size) +int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, + u32 offset, void *dest, size_t size) { - void __iomem *src = sdev->bar[bar] + offset; + int bar = snd_sof_dsp_get_bar_index(sdev, blk_type); + + if (bar < 0) + return bar; + + memcpy_fromio(dest, sdev->bar[bar] + offset, size); - memcpy_fromio(dest, src, size); + return 0; } EXPORT_SYMBOL(sof_block_read); |