in ti_k3_r5_remoteproc.c [494:564]
static int k3_r5_rproc_start(struct rproc *rproc)
{
struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_cluster *cluster = kproc->cluster;
struct mbox_client *client = &kproc->client;
struct device *dev = kproc->dev;
struct k3_r5_core *core;
u32 boot_addr;
int ret;
client->dev = dev;
client->tx_done = NULL;
client->rx_callback = k3_r5_rproc_mbox_callback;
client->tx_block = false;
client->knows_txdone = false;
kproc->mbox = mbox_request_channel(client, 0);
if (IS_ERR(kproc->mbox)) {
ret = -EBUSY;
dev_err(dev, "mbox_request_channel failed: %ld\n",
PTR_ERR(kproc->mbox));
return ret;
}
/*
* Ping the remote processor, this is only for sanity-sake for now;
* there is no functional effect whatsoever.
*
* Note that the reply will _not_ arrive immediately: this message
* will wait in the mailbox fifo until the remote processor is booted.
*/
ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
if (ret < 0) {
dev_err(dev, "mbox_send_message failed: %d\n", ret);
goto put_mbox;
}
boot_addr = rproc->bootaddr;
/* TODO: add boot_addr sanity checking */
dev_dbg(dev, "booting R5F core using boot addr = 0x%x\n", boot_addr);
/* boot vector need not be programmed for Core1 in LockStep mode */
core = kproc->core;
ret = ti_sci_proc_set_config(core->tsp, boot_addr, 0, 0);
if (ret)
goto put_mbox;
/* unhalt/run all applicable cores */
if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
list_for_each_entry_reverse(core, &cluster->cores, elem) {
ret = k3_r5_core_run(core);
if (ret)
goto unroll_core_run;
}
} else {
ret = k3_r5_core_run(core);
if (ret)
goto put_mbox;
}
return 0;
unroll_core_run:
list_for_each_entry_continue(core, &cluster->cores, elem) {
if (k3_r5_core_halt(core))
dev_warn(core->dev, "core halt back failed\n");
}
put_mbox:
mbox_free_channel(kproc->mbox);
return ret;
}