mirror of
https://github.com/apache/nuttx.git
synced 2026-10-01 19:36:28 +00:00
arch/arm/am67: Answer the remoteproc shutdown request in rptun.
The mailbox handler drained the FIFO without checking the message body. That caused shutdown messages to be lost, hence being unable to start/stop the R5 cores from the Linux side. The additions allow checking messages for control and virtqueue types. Shutdown messages fall to the control branch, which ACKs the shutdown request and parks the core in WFI. Virtqueues still work as intended; the only difference is that control messages are now handled correctly. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
This commit is contained in:
parent
0fca32a652
commit
2cb30ac13d
1 changed files with 45 additions and 15 deletions
|
|
@ -93,6 +93,17 @@
|
|||
|
||||
#define AM67_MBOX_USER (3U)
|
||||
|
||||
/* Control messages the Linux side exchanges in the mailbox payload. Any
|
||||
* value outside [READY, END_MSG) is a virtqueue index instead. Values are
|
||||
* from the TI kernel's drivers/remoteproc/omap_remoteproc.h; SHUTDOWN and
|
||||
* SHUTDOWN_ACK are TI additions used by ti_k3_r5_remoteproc.c.
|
||||
*/
|
||||
|
||||
#define RP_MBOX_READY (0xffffff00ul)
|
||||
#define RP_MBOX_SHUTDOWN (0xffffff14ul)
|
||||
#define RP_MBOX_SHUTDOWN_ACK (0xffffff15ul)
|
||||
#define RP_MBOX_END_MSG (0xffffff16ul)
|
||||
|
||||
/* VIM IRQ number on MAIN_R5FSS0_0 for mailbox0_cluster3/user3 */
|
||||
|
||||
#ifndef CONFIG_AM67_RPTUN_IRQ
|
||||
|
|
@ -141,7 +152,6 @@ static const struct rptun_addrenv_s *
|
|||
am67_rptun_get_addrenv(struct rptun_dev_s *dev);
|
||||
static struct resource_table *
|
||||
am67_rptun_get_resource(struct rptun_dev_s *dev);
|
||||
static size_t am67_rptun_get_rsc_size(struct rptun_dev_s *dev);
|
||||
static bool am67_rptun_is_autostart(struct rptun_dev_s *dev);
|
||||
static bool am67_rptun_is_master(struct rptun_dev_s *dev);
|
||||
static int am67_rptun_start(struct rptun_dev_s *dev);
|
||||
|
|
@ -161,7 +171,6 @@ static const struct rptun_ops_s g_am67_rptun_ops =
|
|||
.get_firmware = am67_rptun_get_firmware,
|
||||
.get_addrenv = am67_rptun_get_addrenv,
|
||||
.get_resource = am67_rptun_get_resource,
|
||||
.get_rsc_size = am67_rptun_get_rsc_size,
|
||||
.is_autostart = am67_rptun_is_autostart,
|
||||
.is_master = am67_rptun_is_master,
|
||||
.start = am67_rptun_start,
|
||||
|
|
@ -204,16 +213,6 @@ am67_rptun_get_resource(struct rptun_dev_s *dev)
|
|||
return (struct resource_table *)&g_am67_rsc_table;
|
||||
}
|
||||
|
||||
static size_t am67_rptun_get_rsc_size(struct rptun_dev_s *dev)
|
||||
{
|
||||
/* Return the real size of the extended resource table so that OpenAMP's
|
||||
* remoteproc_set_rsc_table() can find both vdev entries (rptun.c would
|
||||
* otherwise cap the visible region to sizeof(struct rptun_rsc_s)).
|
||||
*/
|
||||
|
||||
return sizeof(struct am67_rsc_s);
|
||||
}
|
||||
|
||||
static bool am67_rptun_is_autostart(struct rptun_dev_s *dev)
|
||||
{
|
||||
return true; /* start rptun thread automatically */
|
||||
|
|
@ -309,14 +308,27 @@ static void am67_rptun_notify_work(void *arg)
|
|||
static int am67_rptun_interrupt(int irq, void *context, void *arg)
|
||||
{
|
||||
struct am67_rptun_dev_s *priv = (struct am67_rptun_dev_s *)arg;
|
||||
bool shutdown = false;
|
||||
bool kick = false;
|
||||
|
||||
/* Drain all messages Linux wrote into FIFO 1. Each read pops one
|
||||
* entry; stop when MSG_STATUS reports 0 pending messages.
|
||||
* entry; stop when MSG_STATUS reports 0 pending messages. A single
|
||||
* interrupt can carry both control messages and virtqueue kicks, so
|
||||
* classify every entry rather than the batch.
|
||||
*/
|
||||
|
||||
while (getreg32(AM67_MBOX_MSG_STATUS(AM67_MBOX_RX_FIFO)) != 0)
|
||||
{
|
||||
(void)getreg32(AM67_MBOX_MESSAGE(AM67_MBOX_RX_FIFO));
|
||||
uint32_t msg = getreg32(AM67_MBOX_MESSAGE(AM67_MBOX_RX_FIFO));
|
||||
|
||||
if (msg == RP_MBOX_SHUTDOWN)
|
||||
{
|
||||
shutdown = true;
|
||||
}
|
||||
else if (msg < RP_MBOX_READY || msg >= RP_MBOX_END_MSG)
|
||||
{
|
||||
kick = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the new-message interrupt status for user-3 / FIFO-1.
|
||||
|
|
@ -333,8 +345,26 @@ static int am67_rptun_interrupt(int irq, void *context, void *arg)
|
|||
putreg32(0, AM67_MBOX_EOI);
|
||||
UP_DSB();
|
||||
|
||||
/* Honour a shutdown request: acknowledge it, then park the core. Linux
|
||||
* polls the TI-SCI WFI status for 2 ms after the ACK and only halts the
|
||||
* R5F once it sees us in WFI, so this must never return.
|
||||
*/
|
||||
|
||||
if (shutdown)
|
||||
{
|
||||
putreg32(RP_MBOX_SHUTDOWN_ACK, AM67_MBOX_MESSAGE(AM67_MBOX_TX_FIFO));
|
||||
UP_DSB();
|
||||
|
||||
up_irq_save();
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
__asm__ __volatile__ ("wfi");
|
||||
}
|
||||
}
|
||||
|
||||
if (priv != NULL && priv->callback != NULL &&
|
||||
work_available(&priv->work))
|
||||
work_available(&priv->work) && kick)
|
||||
{
|
||||
work_queue(HPWORK, &priv->work, am67_rptun_notify_work, priv, 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue