Skip to content

Commit 51b77fe

Browse files
committed
Add Cortex-M7 remoteproc support for iot-gate-imx8plus
Enable the Cortex-M7 co-processor via remoteproc/RPMsg on the iot-gate-imx8plus (NXP i.MX8M Plus). Changes: - Add M7 device tree variant (iot-gate-imx8plus-m7.dts) with reserved memory regions, MU mailboxes, and RPMsg vring buffers. Based on CompuLab reference compulab-imx8m-plus-rpmsg.dtsi. - Add DTS patch to both linux-compulab and linux-balena-bootloader kernel builds. - Add clk_ignore_unused to u-boot mmcargs to prevent Linux from gating M7 clocks while the co-processor is running. - Add imx-rpmsg-tty-autoload recipe to auto-load the imx_rpmsg_tty kernel module at boot via modules-load.d (module cannot be built-in due to NXP Kconfig constraint). - Add M7 DTB to KERNEL_DEVICETREE in layer.conf. Tested on iot-gate-imx8plus with FreeRTOS RPMsg echo firmware loaded via ARM remoteproc-runtime OCI runtime. M7 boots, RPMsg channel established, bidirectional communication confirmed via /dev/ttyRPMSG30. Signed-off-by: Shaun Mulligan <shaun@balena.io>
1 parent 5a33609 commit 51b77fe

File tree

9 files changed

+329
-1
lines changed

9 files changed

+329
-1
lines changed

layers/meta-balena-imx8mplus/conf/layer.conf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ KERNEL_DEVICETREE:iot-gate-imx8plus = " \
3232
compulab/iot-gate-imx8plus.dtb \
3333
compulab/iot-gate-imx8plus-usbdev.dtb \
3434
compulab/iot-gate-imx8plus-m2tpm.dtb \
35+
compulab/iot-gate-imx8plus-m7.dtb \
3536
"
3637

3738
DRAM_CONF:iot-gate-imx8plus="d2d4"
@@ -50,3 +51,6 @@ MACHINE_FEATURES:remove = "efi"
5051
# Can be dropped after updating to a newer kernel which
5152
# is in sync with the wireless regdb provided by Poky
5253
PREFERRED_VERSION:wireless-regdb = "2022.04.08"
54+
55+
# Auto-load imx_rpmsg_tty module at boot for M7 RPMsg communication
56+
IMAGE_INSTALL:append:iot-gate-imx8plus = " imx-rpmsg-tty-autoload"

layers/meta-balena-imx8mplus/recipes-bsp/u-boot/patches/0003-integrate-with-balenaOS.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ index ba8e706f8d1c..61529bde1900 100644
5353
"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
5454
"mmcautodetect=yes\0" \
5555
- "mmcargs=setenv bootargs ${jh_clk} console=${console} root=${mmcroot}\0 " \
56-
+ "mmcargs=setenv bootargs ${jh_clk} ${resin_kernel_root} ${root_opt} ${os_cmdline} "__stringify(BALENA_STAGE2)" \0 " \
56+
+ "mmcargs=setenv bootargs ${jh_clk} clk_ignore_unused ${resin_kernel_root} ${root_opt} ${os_cmdline} "__stringify(BALENA_STAGE2)" \0 " \
5757
"loadbootscript=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${bsp_script};\0" \
5858
"bootscript=echo Running bootscript from mmc ...; " \
5959
"source\0" \
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
imx_rpmsg_tty
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
SUMMARY = "Auto-load imx_rpmsg_tty kernel module at boot"
2+
LICENSE = "MIT"
3+
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
4+
5+
SRC_URI = "file://imx-rpmsg-tty.conf"
6+
7+
do_install() {
8+
install -d ${D}${sysconfdir}/modules-load.d
9+
install -m 0644 ${WORKDIR}/imx-rpmsg-tty.conf ${D}${sysconfdir}/modules-load.d/
10+
}
11+
12+
FILES:${PN} = "${sysconfdir}/modules-load.d/imx-rpmsg-tty.conf"
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
From d43eeecb187a8fd38c832112b84fe98c28105dc8 Mon Sep 17 00:00:00 2001
2+
From: Shaun Mulligan <shaun@balena.io>
3+
Date: Wed, 18 Mar 2026 11:54:23 +0000
4+
Subject: [PATCH] compulab: iot-gate-imx8plus: add M7 remoteproc device tree
5+
6+
Add M7 device tree variant for the bootloader kernel.
7+
8+
Upstream-status: Inappropriate [board configuration]
9+
Signed-off-by: Shaun Mulligan <shaun@balena.io>
10+
---
11+
arch/arm64/boot/dts/compulab/Makefile | 1 +
12+
.../dts/compulab/iot-gate-imx8plus-m7.dts | 112 ++++++++++++++++++
13+
2 files changed, 113 insertions(+)
14+
create mode 100644 arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts
15+
16+
diff --git a/arch/arm64/boot/dts/compulab/Makefile b/arch/arm64/boot/dts/compulab/Makefile
17+
index ccbcf186d0f7..77a5c13866ea 100644
18+
--- a/arch/arm64/boot/dts/compulab/Makefile
19+
+++ b/arch/arm64/boot/dts/compulab/Makefile
20+
@@ -21,6 +21,7 @@ dtb-$(CONFIG_ARCH_MXC) += ucm-imx8m-plus-headless.dtb
21+
dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus.dtb
22+
dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus-usbdev.dtb
23+
dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus-m2tpm.dtb
24+
+dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus-m7.dtb
25+
dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus-brkout_pwm_gpio.dtb
26+
27+
dtb-$(CONFIG_ARCH_MXC) += som-imx8m-plus.dtb
28+
diff --git a/arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts b/arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts
29+
new file mode 100644
30+
index 000000000000..2e246d8eee6f
31+
--- /dev/null
32+
+++ b/arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts
33+
@@ -0,0 +1,112 @@
34+
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
35+
+/*
36+
+ * Copyright 2024 Balena Ltd
37+
+ *
38+
+ * Device tree for CompuLab IOT-GATE-IMX8PLUS with Cortex-M7
39+
+ * remoteproc/RPMsg support enabled.
40+
+ *
41+
+ * Based on CompuLab compulab-imx8m-plus-rpmsg.dtsi reference.
42+
+ */
43+
+
44+
+/dts-v1/;
45+
+
46+
+#include "iot-gate-imx8plus.dts"
47+
+
48+
+/ {
49+
+ model = "CompuLab IOT-GATE-IMX8PLUS (M7 remoteproc)";
50+
+ compatible = "compulab,iot-gate-imx8plus", "compulab,ucm-imx8m-plus-som", "fsl,imx8mp";
51+
+
52+
+ reserved-memory {
53+
+ #address-cells = <2>;
54+
+ #size-cells = <2>;
55+
+ ranges;
56+
+
57+
+ /*
58+
+ * M7 firmware memory: 16MB at 0x80000000 (DRAM).
59+
+ * Remoteproc loads firmware ELF segments here.
60+
+ */
61+
+ m4_reserved: m4@80000000 {
62+
+ no-map;
63+
+ reg = <0 0x80000000 0 0x1000000>;
64+
+ };
65+
+
66+
+ /* Virtio vring buffers for RPMsg communication */
67+
+ vdev0vring0: vdev0vring0@55000000 {
68+
+ reg = <0 0x55000000 0 0x8000>;
69+
+ no-map;
70+
+ };
71+
+
72+
+ vdev0vring1: vdev0vring1@55008000 {
73+
+ reg = <0 0x55008000 0 0x8000>;
74+
+ no-map;
75+
+ };
76+
+
77+
+ /* Resource table shared between Linux and M7 */
78+
+ rsc_table: rsc_table@550ff000 {
79+
+ reg = <0 0x550ff000 0 0x1000>;
80+
+ no-map;
81+
+ };
82+
+
83+
+ /* Shared DMA buffer pool for RPMsg data payloads */
84+
+ vdevbuffer: vdevbuffer@55400000 {
85+
+ compatible = "shared-dma-pool";
86+
+ reg = <0 0x55400000 0 0x100000>;
87+
+ no-map;
88+
+ };
89+
+ };
90+
+
91+
+ /*
92+
+ * Cortex-M7 remoteproc node.
93+
+ * MU (Messaging Unit) mailboxes provide the kick mechanism.
94+
+ * startup-delay-ms gives M7 time to init before first kick.
95+
+ */
96+
+ imx8mp-cm7 {
97+
+ compatible = "fsl,imx8mn-cm7";
98+
+ rsc-da = <0x55000000>;
99+
+ fsl,startup-delay-ms = <500>;
100+
+ clocks = <&clk IMX8MP_CLK_M7_DIV>;
101+
+ mbox-names = "tx", "rx", "rxdb";
102+
+ mboxes = <&mu 0 1
103+
+ &mu 1 1
104+
+ &mu 3 1>;
105+
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>;
106+
+ status = "okay";
107+
+ };
108+
+};
109+
+
110+
+/* Disable peripherals shared with or reserved for the M7 */
111+
+&flexcan1 {
112+
+ status = "disabled";
113+
+};
114+
+
115+
+&flexcan2 {
116+
+ status = "disabled";
117+
+};
118+
+
119+
+&flexspi {
120+
+ status = "disabled";
121+
+};
122+
+
123+
+&pwm4 {
124+
+ status = "disabled";
125+
+};
126+
+
127+
+&sai3 {
128+
+ status = "disabled";
129+
+};
130+
+
131+
+&micfil {
132+
+ status = "disabled";
133+
+};
134+
+
135+
+&sdma3 {
136+
+ status = "disabled";
137+
+};
138+
+
139+
+&uart3 {
140+
+ status = "disabled";
141+
+};
142+
+
143+
+&uart4 {
144+
+ status = "disabled";
145+
+};
146+
--
147+
2.34.1
148+

layers/meta-balena-imx8mplus/recipes-kernel/linux/linux-balena-bootloader_5.15.32.bbappend

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ BALENA_DEFCONFIG_NAME = "iot-gate-imx8plus_defconfig"
77
SRC_URI:append = " \
88
file://arm64-kexec_file-use-more-system-keyrings-to-verify-.patch \
99
file://kexec-KEYS-make-the-code-in-bzImage64_verify_sig-gen.patch \
10+
file://0204-add-iot-gate-imx8plus-m7-device-tree.patch \
1011
"
1112

1213
PACKAGESPLITFUNCS:remove = "split_kernel_module_packages"
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
From 6817fe7c54987b21eb1c35a81f026caa916102cc Mon Sep 17 00:00:00 2001
2+
From: Shaun Mulligan <shaun@balena.io>
3+
Date: Wed, 18 Mar 2026 11:27:06 +0000
4+
Subject: [PATCH] compulab: iot-gate-imx8plus: add M7 remoteproc device tree
5+
6+
Add a secondary device tree variant for the iot-gate-imx8plus that
7+
enables the Cortex-M7 co-processor via remoteproc/RPMsg.
8+
9+
Based on CompuLab reference compulab-imx8m-plus-rpmsg.dtsi from the
10+
linux-compulab_v5.15.32 branch (commit c7be12917bc2).
11+
12+
Upstream-status: Inappropriate [board configuration]
13+
Signed-off-by: Shaun Mulligan <shaun@balena.io>
14+
---
15+
arch/arm64/boot/dts/compulab/Makefile | 1 +
16+
.../dts/compulab/iot-gate-imx8plus-m7.dts | 112 ++++++++++++++++++
17+
2 files changed, 113 insertions(+)
18+
create mode 100644 arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts
19+
20+
diff --git a/arch/arm64/boot/dts/compulab/Makefile b/arch/arm64/boot/dts/compulab/Makefile
21+
index 60205dd04b1f..0eddb8bdb36c 100644
22+
--- a/arch/arm64/boot/dts/compulab/Makefile
23+
+++ b/arch/arm64/boot/dts/compulab/Makefile
24+
@@ -21,6 +21,7 @@ dtb-$(CONFIG_ARCH_MXC) += ucm-imx8m-plus-headless.dtb
25+
dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus.dtb
26+
dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus-usbdev.dtb
27+
dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus-m2tpm.dtb
28+
+dtb-$(CONFIG_ARCH_MXC) += iot-gate-imx8plus-m7.dtb
29+
30+
dtb-$(CONFIG_ARCH_MXC) += som-imx8m-plus.dtb
31+
dtb-$(CONFIG_ARCH_MXC) += som-imx8m-plus_mipi-csi1.dtb
32+
diff --git a/arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts b/arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts
33+
new file mode 100644
34+
index 000000000000..2e246d8eee6f
35+
--- /dev/null
36+
+++ b/arch/arm64/boot/dts/compulab/iot-gate-imx8plus-m7.dts
37+
@@ -0,0 +1,112 @@
38+
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
39+
+/*
40+
+ * Copyright 2024 Balena Ltd
41+
+ *
42+
+ * Device tree for CompuLab IOT-GATE-IMX8PLUS with Cortex-M7
43+
+ * remoteproc/RPMsg support enabled.
44+
+ *
45+
+ * Based on CompuLab compulab-imx8m-plus-rpmsg.dtsi reference.
46+
+ */
47+
+
48+
+/dts-v1/;
49+
+
50+
+#include "iot-gate-imx8plus.dts"
51+
+
52+
+/ {
53+
+ model = "CompuLab IOT-GATE-IMX8PLUS (M7 remoteproc)";
54+
+ compatible = "compulab,iot-gate-imx8plus", "compulab,ucm-imx8m-plus-som", "fsl,imx8mp";
55+
+
56+
+ reserved-memory {
57+
+ #address-cells = <2>;
58+
+ #size-cells = <2>;
59+
+ ranges;
60+
+
61+
+ /*
62+
+ * M7 firmware memory: 16MB at 0x80000000 (DRAM).
63+
+ * Remoteproc loads firmware ELF segments here.
64+
+ */
65+
+ m4_reserved: m4@80000000 {
66+
+ no-map;
67+
+ reg = <0 0x80000000 0 0x1000000>;
68+
+ };
69+
+
70+
+ /* Virtio vring buffers for RPMsg communication */
71+
+ vdev0vring0: vdev0vring0@55000000 {
72+
+ reg = <0 0x55000000 0 0x8000>;
73+
+ no-map;
74+
+ };
75+
+
76+
+ vdev0vring1: vdev0vring1@55008000 {
77+
+ reg = <0 0x55008000 0 0x8000>;
78+
+ no-map;
79+
+ };
80+
+
81+
+ /* Resource table shared between Linux and M7 */
82+
+ rsc_table: rsc_table@550ff000 {
83+
+ reg = <0 0x550ff000 0 0x1000>;
84+
+ no-map;
85+
+ };
86+
+
87+
+ /* Shared DMA buffer pool for RPMsg data payloads */
88+
+ vdevbuffer: vdevbuffer@55400000 {
89+
+ compatible = "shared-dma-pool";
90+
+ reg = <0 0x55400000 0 0x100000>;
91+
+ no-map;
92+
+ };
93+
+ };
94+
+
95+
+ /*
96+
+ * Cortex-M7 remoteproc node.
97+
+ * MU (Messaging Unit) mailboxes provide the kick mechanism.
98+
+ * startup-delay-ms gives M7 time to init before first kick.
99+
+ */
100+
+ imx8mp-cm7 {
101+
+ compatible = "fsl,imx8mn-cm7";
102+
+ rsc-da = <0x55000000>;
103+
+ fsl,startup-delay-ms = <500>;
104+
+ clocks = <&clk IMX8MP_CLK_M7_DIV>;
105+
+ mbox-names = "tx", "rx", "rxdb";
106+
+ mboxes = <&mu 0 1
107+
+ &mu 1 1
108+
+ &mu 3 1>;
109+
+ memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>;
110+
+ status = "okay";
111+
+ };
112+
+};
113+
+
114+
+/* Disable peripherals shared with or reserved for the M7 */
115+
+&flexcan1 {
116+
+ status = "disabled";
117+
+};
118+
+
119+
+&flexcan2 {
120+
+ status = "disabled";
121+
+};
122+
+
123+
+&flexspi {
124+
+ status = "disabled";
125+
+};
126+
+
127+
+&pwm4 {
128+
+ status = "disabled";
129+
+};
130+
+
131+
+&sai3 {
132+
+ status = "disabled";
133+
+};
134+
+
135+
+&micfil {
136+
+ status = "disabled";
137+
+};
138+
+
139+
+&sdma3 {
140+
+ status = "disabled";
141+
+};
142+
+
143+
+&uart3 {
144+
+ status = "disabled";
145+
+};
146+
+
147+
+&uart4 {
148+
+ status = "disabled";
149+
+};
150+
--
151+
2.34.1
152+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_IMX_RPMSG_TTY=y

layers/meta-balena-imx8mplus/recipes-kernel/linux/linux-compulab_%.bbappend

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ SRC_URI:append = " \
1717
file://0103-compulab-iot-gate-imx8plus-fec-update-drive-strength.patch \
1818
"
1919

20+
# M7 remoteproc device tree (kernel 5.15.71 already has imx_rproc fixes)
21+
SRC_URI:append = " \
22+
file://0204-add-iot-gate-imx8plus-m7-device-tree.patch \
23+
"
24+
2025
# Fixes issue where cryptodev module is installed
2126
# along with the kernel image in the initramfs
2227
KERNEL_PACKAGE_NAME="kernel"
@@ -65,3 +70,7 @@ addtask do_merge_config_before_resin_inject after do_configure before kernel_res
6570

6671
# meta-bsp-imx8mp explicitly packages for /lib so let's also append the path set by nonarch_base_libdir for future use of usrmerge
6772
FILES:${KERNEL_PACKAGE_NAME}-modules += "${nonarch_base_libdir}/modules/"
73+
74+
# Auto-load imx_rpmsg_tty at boot. Cannot be built-in (CONFIG_IMX_RPMSG_TTY=y)
75+
# because NXP Kconfig has "depends on HAVE_IMX_RPMSG && m" forcing module-only.
76+
# Use modules-load.d instead.

0 commit comments

Comments
 (0)