From 34575e84cd0a957887c00e4105289003a83c6411 Mon Sep 17 00:00:00 2001 From: Tomas Galbicka Date: Mon, 6 Jan 2025 19:09:55 +0100 Subject: [PATCH] dts: soc: Add DTS MBOX and CM7 boot for NXP RT1180 This commit adds MBOX device tree entry for RT1180. Adds functions to copy and boot CM7 core. Adds MPU region for shared memory without caching. Signed-off-by: Tomas Galbicka --- dts/arm/nxp/nxp_rt118x.dtsi | 2 +- dts/arm/nxp/nxp_rt118x_cm33.dtsi | 34 ++++++++-- dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi | 34 ++++++++-- dts/arm/nxp/nxp_rt118x_cm7.dtsi | 28 ++++++-- soc/nxp/imxrt/Kconfig | 5 +- soc/nxp/imxrt/imxrt118x/Kconfig.defconfig | 2 +- soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c | 5 ++ soc/nxp/imxrt/imxrt118x/soc.c | 82 ++++++++++++++++++++++- 8 files changed, 175 insertions(+), 17 deletions(-) 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