diff --git a/dts/arm/nxp/nxp_rt118x.dtsi b/dts/arm/nxp/nxp_rt118x.dtsi index 4a86f8d4634..b8527a1f0f5 100644 --- a/dts/arm/nxp/nxp_rt118x.dtsi +++ b/dts/arm/nxp/nxp_rt118x.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/dts/arm/nxp/nxp_rt118x_cm33.dtsi b/dts/arm/nxp/nxp_rt118x_cm33.dtsi index 83892d17028..b77431936d9 100644 --- a/dts/arm/nxp/nxp_rt118x_cm33.dtsi +++ b/dts/arm/nxp/nxp_rt118x_cm33.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,6 +26,12 @@ ranges = <0x0 0x30484000 0x10000000>; }; + m7_itcm: itcm@303c0000 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "M7_ITCM"; + reg = <0x303c0000 DT_SIZE_K(256)>; + }; + peripheral: peripheral@50000000 { ranges = <0x0 0x50000000 0x10000000>; }; @@ -48,6 +54,26 @@ }; }; +&peripheral { + mbox1_a: mbox@4220000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x4220000 0x4000>; + interrupts = <21 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + + mbox2_a: mbox@2430000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x2430000 0x4000>; + interrupts = <22 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; +}; + &nvic { arm,num-irq-priority-bits = <3>; }; @@ -60,7 +86,7 @@ &gpio1{ pinmux = <&iomuxc_aon_gpio_aon_00_gpio1_io00>, - <&iomuxc_aon_gpio_aon_01_gpio1_io01>, + <&iomuxc_aon_gpio_aon_01_gpio1_io01>, <&iomuxc_aon_gpio_aon_02_gpio1_io02>, <&iomuxc_aon_gpio_aon_03_gpio1_io03>, <&iomuxc_aon_gpio_aon_04_gpio1_io04>, @@ -91,7 +117,7 @@ &gpio2{ pinmux = <&iomuxc_gpio_emc_b1_00_gpio2_io00>, - <&iomuxc_gpio_emc_b1_01_gpio2_io01>, + <&iomuxc_gpio_emc_b1_01_gpio2_io01>, <&iomuxc_gpio_emc_b1_02_gpio2_io02>, <&iomuxc_gpio_emc_b1_03_gpio2_io03>, <&iomuxc_gpio_emc_b1_04_gpio2_io04>, @@ -126,7 +152,7 @@ &gpio3{ pinmux = <&iomuxc_gpio_emc_b1_32_gpio3_io00>, - <&iomuxc_gpio_emc_b1_33_gpio3_io01>, + <&iomuxc_gpio_emc_b1_33_gpio3_io01>, <&iomuxc_gpio_emc_b1_34_gpio3_io02>, <&iomuxc_gpio_emc_b1_35_gpio3_io03>, <&iomuxc_gpio_emc_b1_36_gpio3_io04>, diff --git a/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi b/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi index 1b082a90fe6..5bd64f0ea60 100644 --- a/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi +++ b/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,6 +26,12 @@ ranges = <0x0 0x20484000 0x10000000>; }; + m7_itcm: itcm@203c0000 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "M7_ITCM"; + reg = <0x203c0000 DT_SIZE_K(256)>; + }; + peripheral: peripheral@40000000 { ranges = <0x0 0x40000000 0x10000000>; }; @@ -48,6 +54,26 @@ }; }; +&peripheral { + mbox1_a: mbox@4220000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x4220000 0x4000>; + interrupts = <21 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + + mbox2_a: mbox@2430000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x2430000 0x4000>; + interrupts = <22 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; +}; + &nvic { arm,num-irq-priority-bits = <3>; }; @@ -60,7 +86,7 @@ &gpio1{ pinmux = <&iomuxc_aon_gpio_aon_00_gpio1_io00>, - <&iomuxc_aon_gpio_aon_01_gpio1_io01>, + <&iomuxc_aon_gpio_aon_01_gpio1_io01>, <&iomuxc_aon_gpio_aon_02_gpio1_io02>, <&iomuxc_aon_gpio_aon_03_gpio1_io03>, <&iomuxc_aon_gpio_aon_04_gpio1_io04>, @@ -91,7 +117,7 @@ &gpio2{ pinmux = <&iomuxc_gpio_emc_b1_00_gpio2_io00>, - <&iomuxc_gpio_emc_b1_01_gpio2_io01>, + <&iomuxc_gpio_emc_b1_01_gpio2_io01>, <&iomuxc_gpio_emc_b1_02_gpio2_io02>, <&iomuxc_gpio_emc_b1_03_gpio2_io03>, <&iomuxc_gpio_emc_b1_04_gpio2_io04>, @@ -126,7 +152,7 @@ &gpio3{ pinmux = <&iomuxc_gpio_emc_b1_32_gpio3_io00>, - <&iomuxc_gpio_emc_b1_33_gpio3_io01>, + <&iomuxc_gpio_emc_b1_33_gpio3_io01>, <&iomuxc_gpio_emc_b1_34_gpio3_io02>, <&iomuxc_gpio_emc_b1_35_gpio3_io03>, <&iomuxc_gpio_emc_b1_36_gpio3_io04>, diff --git a/dts/arm/nxp/nxp_rt118x_cm7.dtsi b/dts/arm/nxp/nxp_rt118x_cm7.dtsi index 91cfc7a95a0..1b9cde67f4c 100644 --- a/dts/arm/nxp/nxp_rt118x_cm7.dtsi +++ b/dts/arm/nxp/nxp_rt118x_cm7.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,6 +47,26 @@ }; }; +&peripheral { + mbox1_b: mbox@4230000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x4230000 0x4000>; + interrupts = <21 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + + mbox2_b: mbox@2440000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x2440000 0x4000>; + interrupts = <22 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; +}; + &nvic { arm,num-irq-priority-bits = <4>; }; @@ -59,7 +79,7 @@ &gpio1{ pinmux = <&iomuxc_aon_gpio_aon_00_gpio1_io00>, - <&iomuxc_aon_gpio_aon_01_gpio1_io01>, + <&iomuxc_aon_gpio_aon_01_gpio1_io01>, <&iomuxc_aon_gpio_aon_02_gpio1_io02>, <&iomuxc_aon_gpio_aon_03_gpio1_io03>, <&iomuxc_aon_gpio_aon_04_gpio1_io04>, @@ -90,7 +110,7 @@ &gpio2{ pinmux = <&iomuxc_gpio_emc_b1_00_gpio2_io00>, - <&iomuxc_gpio_emc_b1_01_gpio2_io01>, + <&iomuxc_gpio_emc_b1_01_gpio2_io01>, <&iomuxc_gpio_emc_b1_02_gpio2_io02>, <&iomuxc_gpio_emc_b1_03_gpio2_io03>, <&iomuxc_gpio_emc_b1_04_gpio2_io04>, @@ -125,7 +145,7 @@ &gpio3{ pinmux = <&iomuxc_gpio_emc_b1_32_gpio3_io00>, - <&iomuxc_gpio_emc_b1_33_gpio3_io01>, + <&iomuxc_gpio_emc_b1_33_gpio3_io01>, <&iomuxc_gpio_emc_b1_34_gpio3_io02>, <&iomuxc_gpio_emc_b1_35_gpio3_io03>, <&iomuxc_gpio_emc_b1_36_gpio3_io04>, diff --git a/soc/nxp/imxrt/Kconfig b/soc/nxp/imxrt/Kconfig index 648b30d750d..c09776302e7 100644 --- a/soc/nxp/imxrt/Kconfig +++ b/soc/nxp/imxrt/Kconfig @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 config SOC_FAMILY_NXP_IMXRT @@ -141,9 +141,10 @@ config NXP_IMX_EXTERNAL_HYPERRAM This setting should be enabled when the application uses HYPERRAM, or an MPU region will be defined to disable cached access to the HYPERRAM memory space. + config SECOND_CORE_MCUX bool "Dual core operation on the RT11xx series" - depends on SOC_SERIES_IMXRT11XX + depends on SOC_SERIES_IMXRT11XX || SOC_SERIES_IMXRT118X help Indicates the second core will be enabled, and the part will run in dual core mode. Enables dual core operation on the RT11xx series, diff --git a/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig b/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig index ebdfa78693b..228c42311df 100644 --- a/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig +++ b/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_SERIES_IMXRT118X diff --git a/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c b/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c index 0e017caa56b..8783ad6a77e 100644 --- a/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c +++ b/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c @@ -11,6 +11,8 @@ #define REGION_FLEXSPI2_SIZE 0x04000000 #define REGION_DTCM_BASE_ADDRESS 0x30000000 #define REGION_DTCM_SIZE 0x00020000 +#define REGION_SRAM2_SHM_BASE_ADDRESS 0x20500000 +#define REGION_SRAM2_SHM_SIZE 0x00008000 #define REGION_FLEXSPI_BASE_ADDRESS 0x38000000 #define REGION_FLEXSPI_SIZE 0x08000000 #define REGION_PERIPHERAL_BASE_ADDRESS 0x50000000 @@ -23,6 +25,9 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_FLASH_ATTR(REGION_FLEXSPI_BASE_ADDRESS, REGION_FLEXSPI_SIZE)), MPU_REGION_ENTRY("DTCM", REGION_DTCM_BASE_ADDRESS, REGION_RAM_NOCACHE_ATTR(REGION_DTCM_BASE_ADDRESS, REGION_DTCM_SIZE)), + MPU_REGION_ENTRY( + "SRAM2_SHM", REGION_SRAM2_SHM_BASE_ADDRESS, + REGION_RAM_NOCACHE_ATTR(REGION_SRAM2_SHM_BASE_ADDRESS, REGION_SRAM2_SHM_SIZE)), MPU_REGION_ENTRY( "PERIPHERAL", REGION_PERIPHERAL_BASE_ADDRESS, REGION_DEVICE_ATTR(REGION_PERIPHERAL_BASE_ADDRESS, REGION_PERIPHERAL_SIZE)), diff --git a/soc/nxp/imxrt/imxrt118x/soc.c b/soc/nxp/imxrt/imxrt118x/soc.c index 261250870a9..1d6362447de 100644 --- a/soc/nxp/imxrt/imxrt118x/soc.c +++ b/soc/nxp/imxrt/imxrt118x/soc.c @@ -26,6 +26,18 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33) +#include +/* Memcpy macro to copy segments from secondary core image stored in flash + * to RAM section that secondary core boots from. + * n is the segment number, as defined in zephyr_image_info.h + */ +#define MEMCPY_SEGMENT(n, _) \ + memcpy((uint32_t *)(((SEGMENT_LMA_ADDRESS_ ## n) - ADJUSTED_LMA) + 0x303C0000), \ + (uint32_t *)(SEGMENT_LMA_ADDRESS_ ## n), \ + (SEGMENT_SIZE_ ## n)) +#endif + /* * Set ELE_STICK_FAILED_STS to 0 when ELE status check is not required, * which is useful when debug reset, where the core has already get the @@ -46,6 +58,17 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); #define ELE_CORE_CM7_ID 0x2 #define EDMA_DID 0x7U +/* When CM33 sets TRDC, CM7 must NOT require TRDC ownership from ELE */ +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_SOC_MIMXRT1189_CM33) +/* When CONFIG_SECOND_CORE_MCUX then TRDC(AON/WAKEUP) ownership cannot be released + * to CM33 and CM7 both in one ELE reset cycle. + * Only CM33 will set TRDC. + */ +#define CM33_SET_TRDC 1U +#else +#define CM33_SET_TRDC 0U +#endif + #ifdef CONFIG_INIT_ARM_PLL static const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { #if defined(CONFIG_SOC_MIMXRT1189_CM33) || defined(CONFIG_SOC_MIMXRT1189_CM7) @@ -507,6 +530,10 @@ __weak void clock_init(void) /* Keep core clock ungated during WFI */ CCM->LPCG[1].LPM0 = 0x33333333; CCM->LPCG[1].LPM1 = 0x33333333; + + /* Let the core clock still running in WAIT mode */ + BLK_CTRL_S_AONMIX->M7_CFG |= BLK_CTRL_S_AONMIX_M7_CFG_CORECLK_FORCE_ON_MASK; + /* Keep the system clock running so SYSTICK can wake up * the system from wfi. */ @@ -646,8 +673,12 @@ void soc_early_init_hook(void) { /* Initialize system clock */ clock_init(); + +#if (defined(CM33_SET_TRDC) && (CM33_SET_TRDC > 0U)) /* Get trdc and enable all access modes for MBC and MRC of TRDCA and TRDCW */ trdc_enable_all_access(); +#endif /* (defined(CM33_SET_TRDC) && (CM33_SET_TRDC > 0U) */ + #if defined(CONFIG_WDT_MCUX_RTWDOG) /* Unmask the watchdog reset channel */ RTWDOG_IF_SET_SRC(0, 1) @@ -660,7 +691,20 @@ void soc_early_init_hook(void) uint32_t mask = SRC_GetResetStatusFlags(SRC_GENERAL_REG); SRC_ClearGlobalSystemResetStatus(SRC_GENERAL_REG, mask); -#endif +#endif /* defined(CONFIG_WDT_MCUX_RTWDOG) */ + +#if (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) + /** + * Copy CM7 core from flash to memory. Note that depending on where the + * user decided to store CM7 code, this is likely going to read from the + * flexspi while using XIP. Provided we DO NOT WRITE TO THE FLEXSPI, + * this operation is safe. + * + * Note that this copy MUST occur before enabling the M33 caching to + * ensure the data is written directly to RAM (since the M4 core will use it) + */ + LISTIFY(SEGMENT_NUM, MEMCPY_SEGMENT, (;)); +#endif /* (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) */ /* Enable data cache */ sys_cache_data_enable(); @@ -673,5 +717,41 @@ void soc_early_init_hook(void) void soc_reset_hook(void) { SystemInit(); + +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33) + Prepare_CM7(0); +#endif } #endif + +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33) + +static int second_core_boot(void) +{ + /* + * RT1180 Specific CM7 Kick Off operation + */ + /* Trigger S401 */ + while ((MU_RT_S3MUA->TSR & MU_TSR_TE0_MASK) == 0) { + ; } /* Wait TR empty */ + MU_RT_S3MUA->TR[0] = 0x17d20106; + while ((MU_RT_S3MUA->RSR & MU_RSR_RF0_MASK) == 0) { + ; } /* Wait RR Full */ + while ((MU_RT_S3MUA->RSR & MU_RSR_RF1_MASK) == 0) { + ; } /* Wait RR Full */ + + /* Response from ELE must be always read */ + __attribute__((unused)) volatile uint32_t result1, result2; + result1 = MU_RT_S3MUA->RR[0]; + result2 = MU_RT_S3MUA->RR[1]; + + /* Deassert Wait */ + BLK_CTRL_S_AONMIX->M7_CFG = + (BLK_CTRL_S_AONMIX->M7_CFG & (~BLK_CTRL_S_AONMIX_M7_CFG_WAIT_MASK)) | + BLK_CTRL_S_AONMIX_M7_CFG_WAIT(0); + + return 0; +} + +SYS_INIT(second_core_boot, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#endif