ASoC: wm_adsp: Refactor compress stream initialisation

Make the code slightly clearer and prepare things for the addition of
multiple compressed streams on a single DSP core.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Charles Keepax 2019-02-22 10:04:19 +00:00 коммит произвёл Mark Brown
Родитель 1e38f069c7
Коммит a792af69b0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 24D68B725D5487D0
1 изменённых файлов: 74 добавлений и 65 удалений

Просмотреть файл

@ -3253,6 +3253,11 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
u32 offset = 0; u32 offset = 0;
int i, ret; int i, ret;
buf->regions = kcalloc(caps->num_regions, sizeof(*buf->regions),
GFP_KERNEL);
if (!buf->regions)
return -ENOMEM;
for (i = 0; i < caps->num_regions; ++i) { for (i = 0; i < caps->num_regions; ++i) {
region = &buf->regions[i]; region = &buf->regions[i];
@ -3287,13 +3292,34 @@ static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf)
buf->avail = 0; buf->avail = 0;
} }
static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf) static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp)
{
struct wm_adsp_compr_buf *buf;
buf = kzalloc(sizeof(*buf), GFP_KERNEL);
if (!buf)
return NULL;
buf->dsp = dsp;
wm_adsp_buffer_clear(buf);
dsp->buffer = buf;
return buf;
}
static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp)
{ {
struct wm_adsp_alg_region *alg_region; struct wm_adsp_alg_region *alg_region;
struct wm_adsp *dsp = buf->dsp; struct wm_adsp_compr_buf *buf;
u32 xmalg, addr, magic; u32 xmalg, addr, magic;
int i, ret; int i, ret;
buf = wm_adsp_buffer_alloc(dsp);
if (!buf)
return -ENOMEM;
alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id);
xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32); xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32);
@ -3303,7 +3329,7 @@ static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf)
return ret; return ret;
if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC)
return -EINVAL; return -ENODEV;
addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr);
for (i = 0; i < 5; ++i) { for (i = 0; i < 5; ++i) {
@ -3323,49 +3349,27 @@ static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf)
buf->host_buf_mem_type = WMFW_ADSP2_XM; buf->host_buf_mem_type = WMFW_ADSP2_XM;
adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); ret = wm_adsp_buffer_populate(buf);
if (ret < 0)
return ret;
adsp_dbg(dsp, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr);
return 0; return 0;
} }
static struct wm_coeff_ctl * static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl)
wm_adsp_find_host_buffer_ctrl(struct wm_adsp_compr_buf *buf)
{ {
struct wm_adsp *dsp = buf->dsp; struct wm_adsp_compr_buf *buf;
struct wm_coeff_ctl *ctl; unsigned int val, reg;
int ret, i;
list_for_each_entry(ctl, &dsp->ctl_list, list) {
if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER)
continue;
if (!ctl->enabled)
continue;
buf->host_buf_mem_type = ctl->alg_region.type;
return ctl;
}
return NULL;
}
static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
{
struct wm_adsp *dsp = buf->dsp;
struct wm_coeff_ctl *ctl;
unsigned int reg;
u32 val;
int i, ret;
ctl = wm_adsp_find_host_buffer_ctrl(buf);
if (!ctl)
return wm_adsp_legacy_host_buf_addr(buf);
ret = wm_coeff_base_reg(ctl, &reg); ret = wm_coeff_base_reg(ctl, &reg);
if (ret) if (ret)
return ret; return ret;
for (i = 0; i < 5; ++i) { for (i = 0; i < 5; ++i) {
ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); ret = regmap_raw_read(ctl->dsp->regmap, reg, &val, sizeof(val));
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -3375,56 +3379,61 @@ static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
usleep_range(1000, 2000); usleep_range(1000, 2000);
} }
if (!val) if (!val) {
adsp_err(ctl->dsp, "Failed to acquire host buffer\n");
return -EIO; return -EIO;
}
buf = wm_adsp_buffer_alloc(ctl->dsp);
if (!buf)
return -ENOMEM;
buf->host_buf_mem_type = ctl->alg_region.type;
buf->host_buf_ptr = be32_to_cpu(val); buf->host_buf_ptr = be32_to_cpu(val);
adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr);
ret = wm_adsp_buffer_populate(buf);
if (ret < 0)
return ret;
adsp_dbg(ctl->dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr);
return 0; return 0;
} }
static int wm_adsp_buffer_init(struct wm_adsp *dsp) static int wm_adsp_buffer_init(struct wm_adsp *dsp)
{ {
struct wm_adsp_compr_buf *buf; struct wm_coeff_ctl *ctl;
int ret; int ret;
buf = kzalloc(sizeof(*buf), GFP_KERNEL); list_for_each_entry(ctl, &dsp->ctl_list, list) {
if (!buf) if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER)
return -ENOMEM; continue;
buf->dsp = dsp; if (!ctl->enabled)
continue;
wm_adsp_buffer_clear(buf); ret = wm_adsp_buffer_parse_coeff(ctl);
if (ret < 0) {
adsp_err(dsp, "Failed to parse coeff: %d\n", ret);
goto error;
}
ret = wm_adsp_buffer_locate(buf); return 0;
if (ret < 0) {
adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret);
goto err_buffer;
} }
buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions, if (!dsp->buffer) {
sizeof(*buf->regions), GFP_KERNEL); /* Fall back to legacy support */
if (!buf->regions) { ret = wm_adsp_buffer_parse_legacy(dsp);
ret = -ENOMEM; if (ret) {
goto err_buffer; adsp_err(dsp, "Failed to parse legacy: %d\n", ret);
goto error;
}
} }
ret = wm_adsp_buffer_populate(buf);
if (ret < 0) {
adsp_err(dsp, "Failed to populate host buffer: %d\n", ret);
goto err_regions;
}
dsp->buffer = buf;
return 0; return 0;
err_regions: error:
kfree(buf->regions); wm_adsp_buffer_free(dsp);
err_buffer:
kfree(buf);
return ret; return ret;
} }