You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/03/30 07:00:23 UTC

[incubator-nuttx] 09/13: rptun: pm_stay when send msg & pm_relax when all tx buffer returned

This is an automated email from the ASF dual-hosted git repository.

pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 1c7e59eafa7e8bd9dbc74333ffee182047ff3d32
Author: ligd <li...@xiaomi.com>
AuthorDate: Wed Feb 9 23:08:22 2022 +0800

    rptun: pm_stay when send msg & pm_relax when all tx buffer returned
    
    Signed-off-by: ligd <li...@xiaomi.com>
---
 drivers/rptun/Kconfig | 10 +++++++++
 drivers/rptun/rptun.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/drivers/rptun/Kconfig b/drivers/rptun/Kconfig
index a3e4487..c1a2415 100644
--- a/drivers/rptun/Kconfig
+++ b/drivers/rptun/Kconfig
@@ -42,4 +42,14 @@ config RPTUN_LOCAL_CPUNAME
 	string "rptun local cpuname"
 	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
diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c
index e4c8a24..f73d6a2 100644
--- a/drivers/rptun/rptun.c
+++ b/drivers/rptun/rptun.c
@@ -35,6 +35,7 @@
 #include <nuttx/semaphore.h>
 #include <nuttx/rptun/openamp.h>
 #include <nuttx/rptun/rptun.h>
+#include <nuttx/power/pm.h>
 #include <nuttx/wqueue.h>
 #include <metal/utilities.h>
 
@@ -43,15 +44,15 @@
  ****************************************************************************/
 
 #ifndef MAX
-#  define MAX(a,b)              ((a) > (b) ? (a) : (b))
+#  define MAX(a,b)                  ((a) > (b) ? (a) : (b))
 #endif
 
 #ifndef ALIGN_UP
-#  define ALIGN_UP(s, a)        (((s) + (a) - 1) & ~((a) - 1))
+#  define ALIGN_UP(s, a)            (((s) + (a) - 1) & ~((a) - 1))
 #endif
 
-#define RPTUNIOC_NONE           0
-#define NO_HOLDER               (INVALID_PROCESS_ID)
+#define RPTUNIOC_NONE               0
+#define NO_HOLDER                   (INVALID_PROCESS_ID)
 
 #define RPTUN_STATUS_FROM_MASTER    0x8
 #define RPTUN_STATUS_MASK           0x7
@@ -71,12 +72,15 @@ struct rptun_priv_s
   struct metal_list            bind;
   struct metal_list            node;
   sem_t                        sem;
+  unsigned long                cmd;
 #ifdef CONFIG_RPTUN_WORKQUEUE
   struct work_s                work;
 #else
   int                          tid;
 #endif
-  unsigned long                cmd;
+#ifdef CONFIG_RPTUN_PM
+  bool                         stay;
+#endif
 };
 
 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)
 {
   FAR struct rptun_priv_s *priv = arg;
@@ -273,6 +310,8 @@ static void rptun_worker(FAR void *arg)
 
   priv->cmd = RPTUNIOC_NONE;
   remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL);
+
+  rptun_pm_action(priv, false);
 }
 
 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)
 {
   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);
 
@@ -743,6 +790,7 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
 
   rptun_unlock();
 
+  rptun_enable_rx_kick(priv);
   return 0;
 }