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 Original line Diff line number Diff line
@@ -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 0;
		return ret;
}

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;


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


	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_adsp_compr_buf *buf;
	struct wm_coeff_ctl *ctl;
	unsigned int val, reg;
	unsigned int reg;
	int ret, i;
	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;


	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) {
		if (ret < 0) {
		adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret);
			adsp_err(dsp, "Failed to parse coeff: %d\n", ret);
		goto err_buffer;
			goto error;
		}
		}


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


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

	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;
}
}