remoteproc: stm32: add capability to detach

A mechanism similar to the shutdown mailbox signal is implemented to
detach a remote processor.

Upon detachment, a signal is sent to the remote firmware, allowing it
to perform specific actions such as stopping rpmsg communication.

The Cortex-M hold boot is also disabled to allow the remote processor
to restart in case of crash.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Tested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20210331073347.8293-3-arnaud.pouliquen@foss.st.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
Arnaud Pouliquen 2021-03-31 09:33:47 +02:00 committed by Bjorn Andersson
parent aca8f94e5b
commit edf696f268
1 changed files with 37 additions and 2 deletions

View File

@ -28,7 +28,7 @@
#define RELEASE_BOOT 1
#define MBOX_NB_VQ 2
#define MBOX_NB_MBX 3
#define MBOX_NB_MBX 4
#define STM32_SMC_RCC 0x82001000
#define STM32_SMC_REG_WRITE 0x1
@ -38,6 +38,7 @@
#define STM32_MBX_VQ1 "vq1"
#define STM32_MBX_VQ1_ID 1
#define STM32_MBX_SHUTDOWN "shutdown"
#define STM32_MBX_DETACH "detach"
#define RSC_TBL_SIZE 1024
@ -336,6 +337,15 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = {
.tx_done = NULL,
.tx_tout = 500, /* 500 ms time out */
},
},
{
.name = STM32_MBX_DETACH,
.vq_id = -1,
.client = {
.tx_block = true,
.tx_done = NULL,
.tx_tout = 200, /* 200 ms time out to detach should be fair enough */
},
}
};
@ -461,6 +471,25 @@ static int stm32_rproc_attach(struct rproc *rproc)
return stm32_rproc_set_hold_boot(rproc, true);
}
static int stm32_rproc_detach(struct rproc *rproc)
{
struct stm32_rproc *ddata = rproc->priv;
int err, dummy_data, idx;
/* Inform the remote processor of the detach */
idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_DETACH);
if (idx >= 0 && ddata->mb[idx].chan) {
/* A dummy data is sent to allow to block on transmit */
err = mbox_send_message(ddata->mb[idx].chan,
&dummy_data);
if (err < 0)
dev_warn(&rproc->dev, "warning: remote FW detach without ack\n");
}
/* Allow remote processor to auto-reboot */
return stm32_rproc_set_hold_boot(rproc, false);
}
static int stm32_rproc_stop(struct rproc *rproc)
{
struct stm32_rproc *ddata = rproc->priv;
@ -597,7 +626,12 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
}
done:
/* Assuming the resource table fits in 1kB is fair */
/*
* Assuming the resource table fits in 1kB is fair.
* Notice for the detach, that this 1 kB memory area has to be reserved in the coprocessor
* firmware for the resource table. On detach, the remoteproc core re-initializes this
* entire area by overwriting it with the initial values stored in rproc->clean_table.
*/
*table_sz = RSC_TBL_SIZE;
return (struct resource_table *)ddata->rsc_va;
}
@ -607,6 +641,7 @@ static const struct rproc_ops st_rproc_ops = {
.start = stm32_rproc_start,
.stop = stm32_rproc_stop,
.attach = stm32_rproc_attach,
.detach = stm32_rproc_detach,
.kick = stm32_rproc_kick,
.load = rproc_elf_load_segments,
.parse_fw = stm32_rproc_parse_fw,