Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit a792af69 authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown
Browse files

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: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1e38f069
Loading
Loading
Loading
Loading
+74 −65
Original line number Diff line number Diff line
@@ -3253,6 +3253,11 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
	u32 offset = 0;
	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) {
		region = &buf->regions[i];

@@ -3287,13 +3292,34 @@ static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf)
	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 *dsp = buf->dsp;
	struct wm_adsp_compr_buf *buf;
	u32 xmalg, addr, magic;
	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);
	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;

	if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC)
		return -EINVAL;
		return -ENODEV;

	addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr);
	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;

	adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr);

	return 0;
}

static struct wm_coeff_ctl *
wm_adsp_find_host_buffer_ctrl(struct wm_adsp_compr_buf *buf)
{
	struct wm_adsp *dsp = buf->dsp;
	struct wm_coeff_ctl *ctl;

	list_for_each_entry(ctl, &dsp->ctl_list, list) {
		if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER)
			continue;

		if (!ctl->enabled)
			continue;
	ret = wm_adsp_buffer_populate(buf);
	if (ret < 0)
		return ret;

		buf->host_buf_mem_type = ctl->alg_region.type;
		return ctl;
	}
	adsp_dbg(dsp, "legacy host_buf_ptr=%x\n", buf->host_buf_ptr);

	return NULL;
	return 0;
}

static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl)
{
	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);
	struct wm_adsp_compr_buf *buf;
	unsigned int val, reg;
	int ret, i;

	ret = wm_coeff_base_reg(ctl, &reg);
	if (ret)
		return ret;

	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)
			return ret;

@@ -3375,56 +3379,61 @@ static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
		usleep_range(1000, 2000);
	}

	if (!val)
	if (!val) {
		adsp_err(ctl->dsp, "Failed to acquire host buffer\n");
		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);
	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;
}


static int wm_adsp_buffer_init(struct wm_adsp *dsp)
{
	struct wm_adsp_compr_buf *buf;
	struct wm_coeff_ctl *ctl;
	int ret;

	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	buf->dsp = dsp;
	list_for_each_entry(ctl, &dsp->ctl_list, list) {
		if (ctl->type != WMFW_CTL_TYPE_HOST_BUFFER)
			continue;

	wm_adsp_buffer_clear(buf);
		if (!ctl->enabled)
			continue;

	ret = wm_adsp_buffer_locate(buf);
		ret = wm_adsp_buffer_parse_coeff(ctl);
		if (ret < 0) {
		adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret);
		goto err_buffer;
			adsp_err(dsp, "Failed to parse coeff: %d\n", ret);
			goto error;
		}

	buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions,
			       sizeof(*buf->regions), GFP_KERNEL);
	if (!buf->regions) {
		ret = -ENOMEM;
		goto err_buffer;
		return 0;
	}

	ret = wm_adsp_buffer_populate(buf);
	if (ret < 0) {
		adsp_err(dsp, "Failed to populate host buffer: %d\n", ret);
		goto err_regions;
	if (!dsp->buffer) {
		/* Fall back to legacy support */
		ret = wm_adsp_buffer_parse_legacy(dsp);
		if (ret) {
			adsp_err(dsp, "Failed to parse legacy: %d\n", ret);
			goto error;
		}
	}

	dsp->buffer = buf;

	return 0;

err_regions:
	kfree(buf->regions);
err_buffer:
	kfree(buf);
error:
	wm_adsp_buffer_free(dsp);
	return ret;
}