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:
Родитель
1e38f069c7
Коммит
a792af69b0
|
@ -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, ®);
|
ret = wm_coeff_base_reg(ctl, ®);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче