Commit c4c432df authored by Shengjiu Wang's avatar Shengjiu Wang Committed by Mathieu Poirier
Browse files

remoteproc: imx_dsp_rproc: Add support of recovery and coredump process



When enabled FW recovery, but is broken because software reset is missed
in this recovery flow. So move software reset from
imx_dsp_runtime_resume() to .load() and clear memory before loading
firmware to make recovery work.

Add call rproc_coredump_set_elf_info() to initialize the elf info for
coredump, otherwise coredump will report error "ELF class is not set".

Fixes: ec0e5549 ("remoteproc: imx_dsp_rproc: Add remoteproc driver for DSP on i.MX")
Signed-off-by: default avatarShengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: default avatarDaniel Baluta <daniel.baluta@nxp.com>
Link: https://lore.kernel.org/r/20250722075225.544319-1-shengjiu.wang@nxp.com


Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
parent c17b750b
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -774,7 +774,6 @@ static int imx_dsp_rproc_prepare(struct rproc *rproc)
{
	struct imx_dsp_rproc *priv = rproc->priv;
	struct device *dev = rproc->dev.parent;
	struct rproc_mem_entry *carveout;
	int ret;

	ret = imx_dsp_rproc_add_carveout(priv);
@@ -785,15 +784,6 @@ static int imx_dsp_rproc_prepare(struct rproc *rproc)

	pm_runtime_get_sync(dev);

	/*
	 * Clear buffers after pm rumtime for internal ocram is not
	 * accessible if power and clock are not enabled.
	 */
	list_for_each_entry(carveout, &rproc->carveouts, node) {
		if (carveout->va)
			memset(carveout->va, 0, carveout->len);
	}

	return  0;
}

@@ -1022,13 +1012,39 @@ static int imx_dsp_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw
	return 0;
}

static int imx_dsp_rproc_load(struct rproc *rproc, const struct firmware *fw)
{
	struct imx_dsp_rproc *priv = rproc->priv;
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	struct rproc_mem_entry *carveout;
	int ret;

	/* Reset DSP if needed */
	if (dsp_dcfg->reset)
		dsp_dcfg->reset(priv);
	/*
	 * Clear buffers after pm rumtime for internal ocram is not
	 * accessible if power and clock are not enabled.
	 */
	list_for_each_entry(carveout, &rproc->carveouts, node) {
		if (carveout->va)
			memset(carveout->va, 0, carveout->len);
	}

	ret = imx_dsp_rproc_elf_load_segments(rproc, fw);
	if (ret)
		return ret;

	return 0;
}

static const struct rproc_ops imx_dsp_rproc_ops = {
	.prepare	= imx_dsp_rproc_prepare,
	.unprepare	= imx_dsp_rproc_unprepare,
	.start		= imx_dsp_rproc_start,
	.stop		= imx_dsp_rproc_stop,
	.kick		= imx_dsp_rproc_kick,
	.load		= imx_dsp_rproc_elf_load_segments,
	.load		= imx_dsp_rproc_load,
	.parse_fw	= imx_dsp_rproc_parse_fw,
	.handle_rsc	= imx_dsp_rproc_handle_rsc,
	.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
@@ -1189,6 +1205,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
		goto err_detach_domains;
	}

	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_XTENSA);

	pm_runtime_enable(dev);

	return 0;
@@ -1214,7 +1232,6 @@ static int imx_dsp_runtime_resume(struct device *dev)
{
	struct rproc *rproc = dev_get_drvdata(dev);
	struct imx_dsp_rproc *priv = rproc->priv;
	const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
	int ret;

	/*
@@ -1235,10 +1252,6 @@ static int imx_dsp_runtime_resume(struct device *dev)
		return ret;
	}

	/* Reset DSP if needed */
	if (dsp_dcfg->reset)
		dsp_dcfg->reset(priv);

	return 0;
}