RPMSG Character Device Driver in Torizon Core 6.2

Hi @gerko,

Sorry for the delay, it took me some time to check how NXP does the device tree on their modules and test these configurations on Apalis iMX8.

I was able to create an overlay and test RPMSG on both Cortex-M cores at the same time and it works.

Here is the overlay blob for you to download: https://share.toradex.com/4ljtmw74cn8k3sr (it will be available for 3 months).

You can enable it in your overlays.txt file, here is what mine looks like (I just added the HMP overlay on top of the default ones for TorizonCore 6):

torizon@apalis-imx8-06980201:~$ cat /boot/ostree/torizon-fde04e5dc537e7d0fb52b2b3582fcf35a6a4c9a662edf9914167a2bada0feb30/dtb/overlays.txt 
fdt_overlays=apalis-imx8_hdmi_overlay.dtbo apalis-imx8_spi1_spidev_overlay.dtbo apalis-imx8_spi2_spidev_overlay.dtbo apalis-imx8_hmp_overlay.dtbo

Here is the info about my setup:

Software summary
------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           5.15.77-6.2.0+git.aa0ff7e3554e #1-TorizonCore SMP PREEMPT Wed Mar 29 15:33:40 UTC 2023
Kernel command line:      pci=nomsi root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/fde04e5dc537e7d0fb52b2b3582fcf35a6a4c9a662edf9914167a2bada0feb30/0
Distro name:              NAME="TorizonCore"
Distro version:           VERSION_ID=6.2.0-build.2
Hostname:                 apalis-imx8-06980201
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Toradex Apalis iMX8QM V1.1 on Apalis Evaluation Board
Toradex version:          0037 V1.1C
Serial number:            06980201
Processor arch:           aarch64
------------------------------------------------------------

And finally, here is the overlay source code:

// Enable RPMSG support for Apalis iMX8

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,apalis-imx8-v1.1",
		     "toradex,apalis-imx8",
		     "fsl,imx8qm";
};

&{/} {
	reserved-memory {

		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		vdev0vring0: vdev0vring0@90000000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90000000 0 0x8000>;
			no-map;
		};

		vdev0vring1: vdev0vring1@90008000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90008000 0 0x8000>;
			no-map;
		};

		vdev1vring0: vdev1vring0@90010000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90010000 0 0x8000>;
			no-map;
		};

		vdev1vring1: vdev1vring1@90018000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90018000 0 0x8000>;
			no-map;
		};

		vdev2vring0: vdev0vring0@90100000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90100000 0 0x8000>;
			no-map;
		};

		vdev2vring1: vdev0vring1@90108000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90108000 0 0x8000>;
			no-map;
		};

		vdev3vring0: vdev1vring0@90110000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90110000 0 0x8000>;
			no-map;
		};

		vdev3vring1: vdev1vring1@90118000 {
			compatible = "shared-dma-pool";
			reg = <0 0x90118000 0 0x8000>;
			no-map;
		};

		vdevbuffer: vdevbuffer {
                        compatible = "shared-dma-pool";
			reg = <0 0x90400000 0 0x100000>;
			no-map;
		};
	};

	rpmsg0: rpmsg@0 {
		compatible = "fsl,imx8qm-rpmsg";
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&lsio_mu5 0 1
			  &lsio_mu5 1 1
			  &lsio_mu5 3 1>;
		mub-partition = <3>;
		vdev-nums = <2>;
		reg = <0 0x90000000 0 0x20000>;
		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
				<&vdev1vring0>, <&vdev1vring1>;
		status = "okay";
	};

	rpmsg1: rpmsg1 {
		compatible = "fsl,imx8qm-rpmsg";
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&lsio_mu6 0 1
			  &lsio_mu6 1 1
			  &lsio_mu6 3 1>;
		mub-partition = <4>;
		vdev-nums = <2>;
		reg = <0 0x90100000 0 0x20000>;
		memory-region = <&vdevbuffer>, <&vdev2vring0>, <&vdev2vring1>,
				<&vdev3vring0>, <&vdev3vring1>;
		status = "okay";
	};
};

&iomuxc {
	pinctrl-0 = <&pinctrl_cam1_gpios>, <&pinctrl_dap1_gpios>,
		    <&pinctrl_esai0_gpios>, <&pinctrl_fec2_gpios>,
		    <&pinctrl_gpio3>, <&pinctrl_gpio4>, <&pinctrl_gpio_keys>,
		    <&pinctrl_gpio_usbh_oc_n>,
		    <&pinctrl_lvds0_i2c0_gpio>, <&pinctrl_lvds1_i2c0_gpios>,
		    <&pinctrl_mipi_dsi_0_1_en>, <&pinctrl_mipi_dsi1_gpios>,
		    <&pinctrl_mlb_gpios>, <&pinctrl_qspi1a_gpios>,
		    <&pinctrl_sata1_act>, <&pinctrl_sim0_gpios>,
		    <&pinctrl_usdhc1_gpios>;
};

&lpuart2 {
	status = "disabled";
};

&lsio_pwm0 {
	status = "disabled";
};

&lsio_pwm1 {
	status = "disabled";
};

The iomuxc, lpuart, and PWM parts are disabled to make the UART that comes from the Cortex-M’s enabled all the time, so you can still see the debug messages from Cortex-M 0 and 1 all the time, while Linux is still running.

After loading the overlay and the multicore demo from NXP, you can simply run:

$ sudo modprobe imx_rpmsg_tty

To load the TTY RPMSG demo inside Linux. You will see a “hello-world” message on the cortex M side and you will also notice that now you have the rpmsg devices enabled now:

torizon@apalis-imx8-06980201:~$ ls /dev/ | grep -i rpmsg
rpmsg_ctrl0
rpmsg_ctrl1
rpmsg_ctrl2
rpmsg_ctrl3
ttyRPMSG30
ttyRPMSG31

About this question, they’re enabled. You can check inside your module by running

$ zcat /proc/config.gz | grep -i rpmsg

This will show the configs related to rpmsg that are enabled by default on TorizonCore.

Let me know if you have any questions.

Best Regards,
Hiago.