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

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

commit e71c9c799acf76c6dfc6e0a0055a555fd5ec6ec3
Author: Jukka Laitinen <[email protected]>
AuthorDate: Mon Sep 14 16:20:58 2026 +0300

    arch/arm/imxrt: Add a function imxrt118x_release_cm7 to start M7 core
    
    Add a function which can be called from M33 core on imx118x to start
    executing on M7 core.
    
    The function:
    - Configures the M7 clock root
    - Releases M7 from reset
    - Asks the secure element to release the M7 (ENABLE_APC)
    - Enables the M7 clock
    
    The function is compiled in when a configuration flag
    CONFIG_IMXRT_CM7_BOOT=y
    
    Signed-off-by: Jukka Laitinen <[email protected]>
---
 arch/arm/src/imxrt/Kconfig               |   5 +
 arch/arm/src/imxrt/Make.defs             |   4 +
 arch/arm/src/imxrt/imxrt118x_start_cm7.c | 236 +++++++++++++++++++++++++++++++
 arch/arm/src/imxrt/imxrt118x_start_cm7.h |  40 ++++++
 4 files changed, 285 insertions(+)

diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index 384e6affb6c..14af2e4392e 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -456,6 +456,11 @@ config IMXRT_ELE
                (arch/arm/src/imxrt/imxrt118x_ele.c).  Present on RT118x-class
                SoCs.
 
+config IMXRT_CM7_BOOT
+       bool
+       default n
+       depends on ARCH_CHIP_MIMXRT1189CVM8C_CM33
+
 menu "i.MX RT Peripheral Selection"
 
 config IMXRT_EDMA
diff --git a/arch/arm/src/imxrt/Make.defs b/arch/arm/src/imxrt/Make.defs
index 67d7aff3a3f..a8c68c843dd 100644
--- a/arch/arm/src/imxrt/Make.defs
+++ b/arch/arm/src/imxrt/Make.defs
@@ -173,3 +173,7 @@ endif
 ifeq ($(CONFIG_IMXRT_ELE),y)
 CHIP_CSRCS += imxrt118x_ele.c
 endif
+
+ifeq ($(CONFIG_IMXRT_CM7_BOOT),y)
+CHIP_CSRCS += imxrt118x_start_cm7.c
+endif
diff --git a/arch/arm/src/imxrt/imxrt118x_start_cm7.c 
b/arch/arm/src/imxrt/imxrt118x_start_cm7.c
new file mode 100644
index 00000000000..fcb8e969326
--- /dev/null
+++ b/arch/arm/src/imxrt/imxrt118x_start_cm7.c
@@ -0,0 +1,236 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/imxrt118x_start_cm7.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "arm_internal.h"
+#include "imxrt118x_ele.h"
+#include "imxrt118x_start_cm7.h"
+#include "hardware/imxrt_ccm.h"
+#include "hardware/rt117x/imxrt117x_dcdc.h"
+#include "hardware/rt118x/imxrt118x_anadig.h"
+#include "hardware/rt118x/imxrt118x_blkctrl.h"
+#include "hardware/rt118x/imxrt118x_gpc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CCM_M7_ROOT_CONFIG          (CCM_CR_CTRL_MUX_SRCSEL(2) | \
+                                     CCM_CR_CTRL_DIV(1))
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imxrt118x_pmu_enable_body_bias_fbb_cm7
+ *
+ * Description:
+ *   Enable forward body bias (FBB) on the LVT core logic.  FBB is required
+ *   for the M7 to reach its 800 MHz HSRUN (OverDrive) frequency
+ *   (IMXRT1180RM Rev. 10 sec. 2.1.3).
+ *
+ *   Follows the "PMU Well Bias Enable Sequence" of RM sec. 24.3.2.3.3.2.
+ *   FBB is implemented in the Cortex-M7 platform only (RM sec. 19.3.3),
+ *   and the second step turns on the CM7 well-bias power switch, so this
+ *   belongs to the M7 release path rather than to generic clock setup.
+ *   The RM requires VDD_SOC_IN and VDD_AON_ANA to be settled beforehand;
+ *   imxrt_clockconfig() has already raised VDD1P0 to 1.125 V by this
+ *   point.
+ *
+ ****************************************************************************/
+
+static int imxrt118x_pmu_enable_body_bias_fbb_cm7(void)
+{
+  int timeout;
+  uint32_t regval;
+
+  /* Step 1/2: configure the well bias. */
+
+  regval  = getreg32(IMXRT_ANADIG_PMU_BIAS_CTRL);
+  regval &= ~(ANADIG_PMU_BIAS_CTRL_WB_NW_LVL_1P8_MASK |
+              ANADIG_PMU_BIAS_CTRL_WB_PW_LVL_1P8_MASK |
+              ANADIG_PMU_BIAS_CTRL_WB_CFG_1P8_MASK);
+  regval |= ANADIG_PMU_BIAS_CTRL_WB_CFG_1P8(ANADIG_PMU_WB_CFG_NWELL_FBB |
+                                    ANADIG_PMU_WB_CFG_PULLDOWN_EN |
+                                    ANADIG_PMU_WB_CFG_AREA(
+                                      ANADIG_PMU_WB_AREA_90UA) |
+                                    ANADIG_PMU_WB_CFG_ADAPTIVE_DIS |
+                                    ANADIG_PMU_WB_CFG_OSC(
+                                      ANADIG_PMU_WB_OSC_FULL)) |
+            ANADIG_PMU_BIAS_CTRL_WB_NW_LVL_1P8(1) |
+            ANADIG_PMU_BIAS_CTRL_WB_PW_LVL_1P8(1);
+  putreg32(regval, IMXRT_ANADIG_PMU_BIAS_CTRL);
+
+  /* Step 3: turn on the CM7 FBB switch and the well-bias regulator. */
+
+  regval  = getreg32(IMXRT_ANADIG_PMU_BIAS_CTRL2);
+  regval |= ANADIG_PMU_BIAS_CTRL2_WB_EN |
+            ANADIG_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8;
+  putreg32(regval, IMXRT_ANADIG_PMU_BIAS_CTRL2);
+
+  /* Step 4: wait for the well bias to stabilise. */
+
+  for (timeout = 10000; timeout != 0; timeout--)
+    {
+      if ((getreg32(IMXRT_ANADIG_PMU_BIAS_CTRL2) &
+           ANADIG_PMU_BIAS_CTRL2_WB_OK) != 0)
+        {
+          return 0;
+        }
+
+      up_udelay(1);
+    }
+
+  syslog(LOG_ERR, "bootloader: FBB not stable (BIAS_CTRL2=0x%08" PRIx32
+         ")\n", getreg32(IMXRT_ANADIG_PMU_BIAS_CTRL2));
+  return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: prepare_m7_power
+ ****************************************************************************/
+
+static int prepare_m7_power(void)
+{
+  uint32_t rootctrl;
+
+  /* Forward body bias is required for HSRUN (IMXRT1180RM Rev. 10
+   * Table 128).
+   */
+
+  if (imxrt118x_pmu_enable_body_bias_fbb_cm7() < 0)
+    {
+      return -ETIMEDOUT;
+    }
+
+  /* Stop root0 before selecting ARM_PLL / 1.  Keep it stopped until the
+   * status register reflects the requested mux and divider, then restart
+   * it and wait for the transition to complete.
+   */
+
+  putreg32(CCM_CR_CTRL_OFF, IMXRT_CCM_CR_CTRL_SET(CCM_CR_M7));
+
+  while ((getreg32(IMXRT_CCM_CR_STAT0(CCM_CR_M7)) &
+          (CCM_CR_STAT0_OFF | CCM_CR_STAT0_CHANGING)) != CCM_CR_STAT0_OFF);
+
+  rootctrl = getreg32(IMXRT_CCM_CR_CTRL(CCM_CR_M7));
+  rootctrl &= ~(CCM_CR_CTRL_MUX_MASK | CCM_CR_CTRL_DIV_MASK);
+  rootctrl |= CCM_M7_ROOT_CONFIG;
+  putreg32(rootctrl, IMXRT_CCM_CR_CTRL(CCM_CR_M7));
+
+  while ((getreg32(IMXRT_CCM_CR_STAT0(CCM_CR_M7)) &
+          (CCM_CR_STAT0_MUX_MASK | CCM_CR_STAT0_DIV_MASK |
+           CCM_CR_STAT0_OFF | CCM_CR_STAT0_CHANGING)) !=
+         (CCM_M7_ROOT_CONFIG | CCM_CR_STAT0_OFF));
+
+  putreg32(CCM_CR_CTRL_OFF, IMXRT_CCM_CR_CTRL_CLR(CCM_CR_M7));
+
+  while (getreg32(IMXRT_CCM_CR_STAT0(CCM_CR_M7)) &
+         (CCM_CR_STAT0_OFF | CCM_CR_STAT0_CHANGING));
+
+  putreg32(DCDC_REG3_REG_FBK_SEL(2) |
+           DCDC_REG3_DISABLE_IDLE_SKIP |
+           DCDC_REG3_DISABLE_PULSE_SKIP,
+           IMXRT_DCDC_REG3);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imxrt118x_release_cm7
+ ****************************************************************************/
+
+int imxrt118x_release_cm7(uintptr_t vtor)
+{
+  uint32_t cfg;
+  int ret;
+
+  /* Prepare the M7 power domain and core clock root.  ARM_PLL is configured
+   * by the M33's imxrt_clockconfig().
+   */
+
+  if (prepare_m7_power() < 0)
+    {
+      return -ETIMEDOUT;
+    }
+
+  /* Keep the M7 platform in RUN during WFI so core exceptions such as
+   * SysTick can wake it without requiring a GPC wakeup source.  This is
+   * done before reset release because the bootloader owns the M7 power
+   * setup.
+   */
+
+  modifyreg32(IMXRT_GPC_CM7_MODE_CTRL,
+              GPC_CM_MODE_CTRL_TARGET_MASK,
+              GPC_CM_MODE_CTRL_TARGET(GPC_CM_MODE_TARGET_RUN));
+  modifyreg32(IMXRT_GPC_CM_MISC(1),
+              GPC_CM_MISC_SLEEP_HOLD_EN, 0);
+
+  /* Program the M7 initial VTOR and force its clocks on. */
+
+  cfg = getreg32(IMXRT_AON_M7_CFG);
+  cfg = (cfg & ~AON_M7_CFG_INITVTOR_MASK) |
+        AON_M7_CFG_INITVTOR(vtor >> AON_M7_CFG_INITVTOR_SHIFT) |
+        AON_M7_CFG_HCLK_FORCE_ON |
+        AON_M7_CFG_CORECLK_FORCE_ON;
+  putreg32(cfg, IMXRT_AON_M7_CFG);
+
+  /* Release the M7 from reset (write-once). */
+
+  putreg32(getreg32(IMXRT_SRC_SCR) | SRC_SCR_BT_RELEASE_M7, IMXRT_SRC_SCR);
+
+  /* Ask ELE to release the M7. */
+
+  ret = imxrt118x_ele_enable_apc();
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Kick the M7 by toggling its clock around WAIT deassertion.
+   */
+
+  putreg32(0, IMXRT_CCM_LPCG_DIR(0));
+
+  putreg32(getreg32(IMXRT_AON_M7_CFG) & ~AON_M7_CFG_WAIT, IMXRT_AON_M7_CFG);
+
+  putreg32(CCM_LPCG_DIR_ON, IMXRT_CCM_LPCG_DIR(0));
+
+  return 0;
+}
diff --git a/arch/arm/src/imxrt/imxrt118x_start_cm7.h 
b/arch/arm/src/imxrt/imxrt118x_start_cm7.h
new file mode 100644
index 00000000000..c5edc4ae369
--- /dev/null
+++ b/arch/arm/src/imxrt/imxrt118x_start_cm7.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/imxrt118x_start_cm7.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT118X_START_CM7_H
+#define __ARCH_ARM_SRC_IMXRT_IMXRT118X_START_CM7_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int imxrt118x_release_cm7(uintptr_t vtor);
+
+#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT118X_START_CM7_H */

Reply via email to