rptun: pm_stay when send msg & pm_relax when all tx buffer returned
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
f0ba2f0286
commit
1c7e59eafa
@ -42,4 +42,14 @@ config RPTUN_LOCAL_CPUNAME
|
|||||||
string "rptun local cpuname"
|
string "rptun local cpuname"
|
||||||
default LIBC_HOSTNAME
|
default LIBC_HOSTNAME
|
||||||
|
|
||||||
|
config RPTUN_PM
|
||||||
|
bool "rptun power management"
|
||||||
|
depends on PM
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
If TX/RX buffer is supplied and powered by each CPU.
|
||||||
|
And when one CPU in DEEP sleep, then it's buffer will
|
||||||
|
goto RAM-retention mode, can't access from another CPU.
|
||||||
|
So, we provide this method to resolve this.
|
||||||
|
|
||||||
endif # RPTUN
|
endif # RPTUN
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
#include <nuttx/rptun/openamp.h>
|
#include <nuttx/rptun/openamp.h>
|
||||||
#include <nuttx/rptun/rptun.h>
|
#include <nuttx/rptun/rptun.h>
|
||||||
|
#include <nuttx/power/pm.h>
|
||||||
#include <nuttx/wqueue.h>
|
#include <nuttx/wqueue.h>
|
||||||
#include <metal/utilities.h>
|
#include <metal/utilities.h>
|
||||||
|
|
||||||
@ -43,15 +44,15 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
# define MAX(a,b) ((a) > (b) ? (a) : (b))
|
# define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ALIGN_UP
|
#ifndef ALIGN_UP
|
||||||
# define ALIGN_UP(s, a) (((s) + (a) - 1) & ~((a) - 1))
|
# define ALIGN_UP(s, a) (((s) + (a) - 1) & ~((a) - 1))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RPTUNIOC_NONE 0
|
#define RPTUNIOC_NONE 0
|
||||||
#define NO_HOLDER (INVALID_PROCESS_ID)
|
#define NO_HOLDER (INVALID_PROCESS_ID)
|
||||||
|
|
||||||
#define RPTUN_STATUS_FROM_MASTER 0x8
|
#define RPTUN_STATUS_FROM_MASTER 0x8
|
||||||
#define RPTUN_STATUS_MASK 0x7
|
#define RPTUN_STATUS_MASK 0x7
|
||||||
@ -71,12 +72,15 @@ struct rptun_priv_s
|
|||||||
struct metal_list bind;
|
struct metal_list bind;
|
||||||
struct metal_list node;
|
struct metal_list node;
|
||||||
sem_t sem;
|
sem_t sem;
|
||||||
|
unsigned long cmd;
|
||||||
#ifdef CONFIG_RPTUN_WORKQUEUE
|
#ifdef CONFIG_RPTUN_WORKQUEUE
|
||||||
struct work_s work;
|
struct work_s work;
|
||||||
#else
|
#else
|
||||||
int tid;
|
int tid;
|
||||||
#endif
|
#endif
|
||||||
unsigned long cmd;
|
#ifdef CONFIG_RPTUN_PM
|
||||||
|
bool stay;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rptun_bind_s
|
struct rptun_bind_s
|
||||||
@ -250,6 +254,39 @@ static void rptun_unlock(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_RPTUN_PM
|
||||||
|
static inline void rptun_pm_action(FAR struct rptun_priv_s *priv,
|
||||||
|
bool stay)
|
||||||
|
{
|
||||||
|
irqstate_t flags;
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
|
|
||||||
|
if (stay && !priv->stay)
|
||||||
|
{
|
||||||
|
pm_stay(0, PM_IDLE);
|
||||||
|
priv->stay = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stay && priv->stay && !rpmsg_buffer_nused(&priv->rvdev, false))
|
||||||
|
{
|
||||||
|
pm_relax(0, PM_IDLE);
|
||||||
|
priv->stay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rptun_enable_rx_kick(FAR struct rptun_priv_s *priv)
|
||||||
|
{
|
||||||
|
virtqueue_enable_cb(priv->rvdev.svq);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define rptun_pm_action(priv, stay)
|
||||||
|
# define rptun_enable_rx_kick(priv)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void rptun_worker(FAR void *arg)
|
static void rptun_worker(FAR void *arg)
|
||||||
{
|
{
|
||||||
FAR struct rptun_priv_s *priv = arg;
|
FAR struct rptun_priv_s *priv = arg;
|
||||||
@ -273,6 +310,8 @@ static void rptun_worker(FAR void *arg)
|
|||||||
|
|
||||||
priv->cmd = RPTUNIOC_NONE;
|
priv->cmd = RPTUNIOC_NONE;
|
||||||
remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
|
remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
|
||||||
|
|
||||||
|
rptun_pm_action(priv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rptun_post(FAR struct rptun_priv_s *priv)
|
static void rptun_post(FAR struct rptun_priv_s *priv)
|
||||||
@ -417,6 +456,14 @@ static int rptun_stop(FAR struct remoteproc *rproc)
|
|||||||
static int rptun_notify(FAR struct remoteproc *rproc, uint32_t id)
|
static int rptun_notify(FAR struct remoteproc *rproc, uint32_t id)
|
||||||
{
|
{
|
||||||
FAR struct rptun_priv_s *priv = rproc->priv;
|
FAR struct rptun_priv_s *priv = rproc->priv;
|
||||||
|
FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev;
|
||||||
|
FAR struct virtqueue *vq = rvdev->svq;
|
||||||
|
|
||||||
|
if (rvdev->vdev && vq &&
|
||||||
|
rvdev->vdev->vrings_info[vq->vq_queue_index].notifyid == id)
|
||||||
|
{
|
||||||
|
rptun_pm_action(priv, true);
|
||||||
|
}
|
||||||
|
|
||||||
RPTUN_NOTIFY(priv->dev, RPTUN_NOTIFY_ALL);
|
RPTUN_NOTIFY(priv->dev, RPTUN_NOTIFY_ALL);
|
||||||
|
|
||||||
@ -743,6 +790,7 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
|
|||||||
|
|
||||||
rptun_unlock();
|
rptun_unlock();
|
||||||
|
|
||||||
|
rptun_enable_rx_kick(priv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user