[alsa-devel] [PATCH] ASoC: wm_adsp: Split firmware load into smaller chunks
The firmware files can be quite large and allocating the whole firmware a single DMA safe buffer can be problematic if the system is under a high memory load. Ease the requirements slightly by writing the firmware out in page sized chunks.
Signed-off-by: Charles Keepax ckeepax@opensource.wolfsonmicro.com --- sound/soc/codecs/wm_adsp.c | 50 ++++++++++++++++++++++++++++--------------- 1 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f9fd564..937af6f 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -684,24 +684,38 @@ static int wm_adsp_load(struct wm_adsp *dsp) }
if (reg) { - buf = wm_adsp_buf_alloc(region->data, - le32_to_cpu(region->len), - &buf_list); - if (!buf) { - adsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; - } + size_t to_write = PAGE_SIZE; + size_t remain = le32_to_cpu(region->len); + const u8 *data = region->data; + + while (remain > 0) { + if (remain < PAGE_SIZE) + to_write = remain; + + buf = wm_adsp_buf_alloc(data, + to_write, + &buf_list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + ret = -ENOMEM; + goto out_fw; + }
- ret = regmap_raw_write_async(regmap, reg, buf->buf, - le32_to_cpu(region->len)); - if (ret != 0) { - adsp_err(dsp, - "%s.%d: Failed to write %d bytes at %d in %s: %d\n", - file, regions, - le32_to_cpu(region->len), offset, - region_name, ret); - goto out_fw; + ret = regmap_raw_write_async(regmap, reg, + buf->buf, + to_write); + if (ret != 0) { + adsp_err(dsp, + "%s.%d: Failed to write %d bytes at %d in %s: %d\n", + file, regions, + to_write, offset, + region_name, ret); + goto out_fw; + } + + data += to_write; + reg += to_write / 2; + remain -= to_write; } }
On Wed, Mar 05, 2014 at 02:28:16PM +0000, Charles Keepax wrote:
The firmware files can be quite large and allocating the whole firmware a single DMA safe buffer can be problematic if the system is under a high memory load. Ease the requirements slightly by writing the firmware out in page sized chunks.
Applied, thanks.
On Wed, Mar 05, 2014 at 02:28:16PM +0000, Charles Keepax wrote:
The firmware files can be quite large and allocating the whole firmware a single DMA safe buffer can be problematic if the system is under a high memory load. Ease the requirements slightly by writing the firmware out in page sized chunks.
While looking at some other related stuff it occurred to me that while this is probably what you want for your backported code for upstream you probably want to just convert to vmalloc() - SPI will do DMA mappings in page sized chunks in order to support this so you get a similar effect but without needing to split into multiple physical writes so it can all be pushed down into hardware for best performance.
On Wed, Mar 12, 2014 at 12:29:06AM +0000, Mark Brown wrote:
On Wed, Mar 05, 2014 at 02:28:16PM +0000, Charles Keepax wrote:
The firmware files can be quite large and allocating the whole firmware a single DMA safe buffer can be problematic if the system is under a high memory load. Ease the requirements slightly by writing the firmware out in page sized chunks.
While looking at some other related stuff it occurred to me that while this is probably what you want for your backported code for upstream you probably want to just convert to vmalloc() - SPI will do DMA mappings in page sized chunks in order to support this so you get a similar effect but without needing to split into multiple physical writes so it can all be pushed down into hardware for best performance.
Sounds sensible I will look at testing this and doing a patch for it.
Thanks, Charles
participants (2)
-
Charles Keepax
-
Mark Brown