diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 12dc93059c0a..36417866f1c0 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1911,6 +1911,55 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, return 0; } +static int wm_adsp_write_blocks(struct wm_adsp *dsp, const u8 *data, size_t len, + unsigned int reg, struct list_head *list, + size_t burst_multiple) + +{ + size_t to_write = PAGE_SIZE - (PAGE_SIZE % burst_multiple); + size_t remain = len; + struct wm_adsp_buf *buf; + unsigned int addr_div; + int ret; + + switch (dsp->type) { + case WMFW_ADSP1: + case WMFW_ADSP2: + addr_div = 2; + break; + default: + addr_div = 1; + break; + } + + while (remain > 0) { + if (remain < to_write) + to_write = remain; + + buf = wm_adsp_buf_alloc(data, to_write, list); + if (!buf) { + adsp_err(dsp, "Out of memory\n"); + return -ENOMEM; + } + + ret = regmap_raw_write_async(dsp->regmap, reg, + buf->buf, to_write); + if (ret != 0) { + adsp_err(dsp, + "Failed to write %zd bytes at %d\n", + to_write, reg); + + return ret; + } + + data += to_write; + reg += to_write / addr_div; + remain -= to_write; + } + + return 0; +} + static int wm_adsp_load(struct wm_adsp *dsp) { LIST_HEAD(buf_list); @@ -1925,10 +1974,10 @@ static int wm_adsp_load(struct wm_adsp *dsp) const struct wm_adsp_region *mem; const char *region_name; char *file, *text = NULL; - struct wm_adsp_buf *buf; unsigned int reg; int regions = 0; int ret, offset, type, sizes; + unsigned int burst_multiple; file = kzalloc(PAGE_SIZE, GFP_KERNEL); if (file == NULL) @@ -2056,6 +2105,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) region = (void *)&(firmware->data[pos]); region_name = "Unknown"; reg = 0; + burst_multiple = 4; text = NULL; offset = le32_to_cpu(region->offset) & 0xffffff; type = be32_to_cpu(region->type) & 0xff; @@ -2122,38 +2172,17 @@ static int wm_adsp_load(struct wm_adsp *dsp) } if (reg) { - size_t to_write = PAGE_SIZE; - size_t remain = le32_to_cpu(region->len); - const u8 *data = region->data; + ret = wm_adsp_write_blocks(dsp, region->data, + le32_to_cpu(region->len), + reg, &buf_list, + burst_multiple); - 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, - to_write); - if (ret != 0) { - adsp_err(dsp, - "%s.%d: Failed to write %zd 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; + if (ret != 0) { + adsp_err(dsp, + "%s.%d: Failed writing data at %d in %s: %d\n", + file, regions, + offset, region_name, ret); + goto out_fw; } }