lipengfei28 commented on code in PR #16798:
URL: https://github.com/apache/nuttx/pull/16798#discussion_r2260121634


##########
arch/arm64/src/imx9/imx9_mu.c:
##########
@@ -0,0 +1,409 @@
+/****************************************************************************
+ * arch/arm64/src/imx9/imx9_mu.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: 2024 NXP
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "imx9_mu.h"
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/imx95/imx95_memorymap.h"
+#include "hardware/imx9_mu.h"
+#include <debug.h>
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_OF_GPI    4
+#define MSG_INT_MASK ((1 << IMX9_MU_RR_REGARRAY_SIZE) - 1)
+#define GPI_INT_MASK ((1 << NR_OF_GPI) - 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct imx9_mudev_s
+{
+  uint32_t mubase;
+  uint32_t irq;
+  imx9_mu_msg_callback_t msg_callback;
+  imx9_mu_gpi_callback_t gpi_callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imx9_mudev_s g_mu2_dev = /* clang-format off */
+{
+  .mubase = IMX9_MU2_MUA_BASE,
+  .irq = IMX9_IRQ_MU2_A
+}; /* clang-format on */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int imx9_mu_interrupt(int irq, void *context, void *args)
+{
+  struct imx9_mudev_s *dev = args;
+
+  uint32_t sr  = getreg32(IMX9_MU_SR(dev->mubase));
+  uint32_t rsr = getreg32(IMX9_MU_RSR(dev->mubase));
+  uint32_t gsr = getreg32(IMX9_MU_GSR(dev->mubase));
+
+  ipcinfo("MU irq=%d, SR=0x%04x, RSR=0x%04x, GSR=0x%04x\n", irq, sr, rsr,
+          gsr);
+
+  if (sr & IMX9_MU_SR_RFP_FLAG)
+    {
+      for (int i = 0; i < IMX9_MU_RR_REGARRAY_SIZE; i++)
+        {
+          if (rsr & (1 << i))
+            {
+              uint32_t msg = imx95_mu_receive_msg_non_blocking(dev, i);
+
+              if (dev->msg_callback)
+                {
+                  dev->msg_callback(i, msg, dev);
+                }
+            }
+        }
+
+      for (int i = 0; i < NR_OF_GPI; i++)
+        {
+          if (gsr & (1 << i))
+            {
+              putreg32((1 << i), IMX9_MU_GSR(dev->mubase));
+
+              if (dev->gpi_callback)
+                {
+                  dev->gpi_callback(i, dev);
+                }
+            }
+        }
+    }
+
+  /* Unknown interrupt flag which occurs when A55 shuts down */
+
+  if (sr & 0x80)
+    {
+      /* TODO how to clear this flag? A W1C doesn't seem to work.. */
+
+      putreg32(0x80, IMX9_MU_SR(dev->mubase));
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imx95_mu_init
+ *
+ * Description:
+ *   Initialize mu
+ *
+ * Input Parameters:
+ *   index   - The index of mu
+ *
+ * Returned Value:
+ *   imx9_mudev_s struct is returned on success. NULL is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+struct imx9_mudev_s *imx95_mu_init(int index)
+{
+  struct imx9_mudev_s *priv;
+
+  if ((index == 2))
+    {
+      priv = &g_mu2_dev;
+    }
+
+  else
+    {
+      return NULL;
+    }
+
+  irq_attach(priv->irq, imx9_mu_interrupt, priv);
+  up_enable_irq(priv->irq);
+
+  priv->gpi_callback = NULL;
+  priv->msg_callback = NULL;
+
+  return priv;
+}
+
+/****************************************************************************
+ * Name: imx95_mu_subscribe_msg
+ *
+ * Description:
+ *  Subscribe msg, when the irq occur,the msg callback will be called.
+ *
+ * Input Parameters:
+ *   priv             - The mu dev will be used
+ *   msg_int_bitfield - Enable correspond bit receive irq
+ *   callback         - The call back will called when the irq occur
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void imx95_mu_subscribe_msg(struct imx9_mudev_s *priv,
+                            uint32_t msg_int_bitfield,
+                            imx9_mu_msg_callback_t callback)
+{
+  priv->msg_callback = callback;
+  putreg32(msg_int_bitfield & MSG_INT_MASK, IMX9_MU_RCR(priv->mubase));
+}
+
+/****************************************************************************
+ * Name: imx95_mu_subscribe_gpi
+ *
+ * Description:
+ *  Subscribe msg, when the irq occur,the msg callback will be called.
+ *
+ * Input Parameters:
+ *   priv             - The mu dev will be used
+ *   gpi_int_enable   - Enable correspond bit general purpose irq
+ *   callback         - The call back will called when the irq occur
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void imx95_mu_subscribe_gpi(struct imx9_mudev_s *priv,
+                            uint32_t gpi_int_enable,
+                            imx9_mu_gpi_callback_t callback)
+{
+  priv->gpi_callback = callback;
+  putreg32(gpi_int_enable & GPI_INT_MASK, IMX9_MU_GIER(priv->mubase));
+}
+
+/****************************************************************************
+ * Name: imx95_mu_deinit
+ *
+ * Description:
+ *   Deinit mu
+ *
+ * Input Parameters:
+ *   priv             - The mu dev will be deinit
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void imx95_mu_deinit(struct imx9_mudev_s *priv)
+{
+  up_disable_irq(priv->irq);
+}
+
+/****************************************************************************
+ * Name: imx95_mu_send_msg_non_blocking
+ *
+ * Description:
+ *  When the mu is busy, will return err
+ *
+ * Input Parameters:
+ *   priv             - The mu dev will be used
+ *   reg_index        - Which one transmit reg to be used
+ *   msg              - The msgto be send
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success. A negated errno value is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+int imx95_mu_send_msg_non_blocking(struct imx9_mudev_s *priv,
+                                   uint32_t reg_index, uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg nonblocking idx=%d, msg=%d\n", reg_index, msg);
+
+  if ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    {
+      return -EBUSY;
+    }
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));
+  return OK;
+}
+
+/****************************************************************************
+ * Name: imx95_mu_send_msg
+ *
+ * Description:
+ *  Send msg blocking
+ *
+ * Input Parameters:
+ *   priv             - The mu dev will be used
+ *   reg_index        - Which one transmit reg to be used
+ *   msg              - The msgto be send
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void imx95_mu_send_msg(struct imx9_mudev_s *priv, uint32_t reg_index,
+                       uint32_t msg)
+{
+  assert(reg_index < IMX9_MU_TR_REGARRAY_SIZE);
+
+  ipcinfo("MU send msg idx=%d, msg=%d\n", reg_index, msg);
+
+  /* Wait TX register to be empty. */
+
+  while ((getreg32(IMX9_MU_TSR(priv->mubase)) & (1UL << reg_index)) == 0UL)
+    ;
+
+  putreg32(msg, IMX9_MU_TR1(priv->mubase) + (reg_index * sizeof(uint32_t)));

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to