I found something weird. 4.14 kernel or 5.x - the same issue. Modifying 4.14 Kconfig files I made imx_rpmsg driver loadable, put printk’s to trace MU driver and imx_rpmsg calls. Issue is somewhat fuzzy behaving device tree. I don’t know, but if cat /sys/firmware/devicetree/../rpmsg/status gives disabled, then even don’t try launching M4 from Linux, RPMSG won’t work. If status is OK, then starting M4 by m4fwloader, JTAG debugger, perhaps remoteproc as well should make RPMSG working, no matter is imx_rpmsg loaded before launching M4 or after.
The problem is something flips rpmsg DT status in /sys/firmware from okay to disabled.
Without doing any changes to DT, using the same *.dtb file, one time /sys status matches DT and is okay, and another time it doesn’t match DT and is disabled:
Loading M4 FW and then issuing bootaux - makes imx_rpmsg /sys status okay.
Not loading M4 FW after reset and just issuing to uninitialized memory bootuax 80800000 - makes imx_rpmsg /sys status okay again :-).
Not touching bootaux, using JTAG debugger without any cool Linux kernel support or something, setting HW breakpoint at /init/main.c start_kernel() routine, reaching that breakpoint (so it stops for a while), then continuing executing … makes imx_rpmsg /sys status okay again.
Not using bootaux or JTAG renders /sys/firmware/devicetree/../rpmsg/status disabled. Since disabled, driver isn’t probed, which gives no chance to get RPMSG working launching M4 from Linux.
I’m picking main hair why it is so. Made many different searches though kernel sources to find what could render imx_rpmsg status disabled, no results yet.
Any advice how to figure why status could flip from okay in dtb to disabled in /sys? p4 above suggests something like missing cache flush, missing sync barrier, broken RAM, etc.
Loading dtb file in U-Boot and inspecting DT settings using fdt list and fdt print confirms okay. But Linux sometimes doesn’t agree with this.
Well, I have workaround for oddities mentioned in my previous message. In short, for some odd reasons Linux may flip status of first rpmsg device from okay to disabled. My workaround is to disable first rpmsg instance and create new one. Renaming first instance didn’t work, mystery. Let me give you some details, which may help understanding better or reproducing.
Disabling first rpmsg, adding second rpmsg, reserving memory for vring:
diff --git a/imx7d-colibri-eval-v3.dts~ b/imx7d-colibri-eval-v3.dts
index 3d2b48e..9af58c9 100644
--- a/imx7d-colibri-eval-v3.dts~
+++ b/imx7d-colibri-eval-v3.dts
@@ -49,8 +49,48 @@
compatible = "toradex,colibri-imx7d-eval-v3",
"toradex,colibri-imx7d",
"fsl,imx7d";
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ rpmsg-vrings@0x8fff0000 {
+ compatible = "shared-dma-pool";
+ reg = <0x8fff0000 0x10000>;
+ no-map;
+ };
+ };
+ soc {
+ rpmsg1 {
+ vdev-nums = <1>;
+ reg = <0x8fff0000 0x10000>;
+ status = "okay";
+
+ compatible = "fsl,imx7d-rpmsg";
+ /* up to now, the following channels are used in imx rpmsg
+ * - tx1/rx1: messages channel.
+ * - general interrupt1: remote proc finish re-init rpmsg stack
+ * when A core is partition reset.
+ */
+ mbox-names = "tx", "rx", "rxdb";
+ mboxes = <&mu 0 1
+ &mu 1 1
+ &mu 3 1>;
+ };
+ };
+};
+
+
+/* defined in imx7s.dtsi, disabled. Reenabled and specified VRING address
+ in imx7-colibri.dtsi.
+ Disabled it and redefine new instance
+*/
+&rpmsg {
+ status = "disabled";
};
+
&usbotg2 {
vbus-supply = <®_usbh_vbus>;
status = "okay";
Check dtb:
[upload|bCWroN70x4aYXd2TRSRjKjgJ8JI=]
Result, 2nd rpmsg instance visible to Linux:
[upload|kBvcBdbKcEI3719ro6Ybztm+x0Q=]
Since status is OK, imx_rpmsg driver can be successfully probed. I was able to launch M4 from Linux and got RPMSG working. Remoteproc should work as well, will check later
OK, it turns out that guilty for these issues is U-Boot. It checks if M4 was started or just attempted to start and disables in DT “fsl,imx7d-rpmsg”.
Here’s excerpt from u-boot-2020.07/u-boot-toradex/board/toradex/colibri_imx7/colibri_imx7.c:
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
int ft_board_setup(void *blob, bd_t *bd)
{
#if defined(CONFIG_IMX_BOOTAUX) && defined(CONFIG_ARCH_FIXUP_FDT_MEMORY)
int up;
up = arch_auxiliary_core_check_up(0);
if (up) {
int ret;
int areas = 1;
u64 start[2], size[2];
/*
* Reserve 1MB of memory for M4 (1MiB is also the minimum
* alignment for Linux due to MMU section size restrictions).
*/
start[0] = gd->bd->bi_dram[0].start;
size[0] = SZ_256M - SZ_1M;
/* If needed, create a second entry for memory beyond 256M */
if (gd->bd->bi_dram[0].size > SZ_256M) {
start[1] = gd->bd->bi_dram[0].start + SZ_256M;
size[1] = gd->bd->bi_dram[0].size - SZ_256M;
areas = 2;
}
ret = fdt_set_usable_memory(blob, start, size, areas);
if (ret) {
eprintf("Cannot set usable memory\n");
return ret;
}
} else {
int off;
off = fdt_node_offset_by_compatible(blob, -1,
"fsl,imx7d-rpmsg");
if (off > 0)
fdt_status_disabled(blob, off);
}
Please remove removal of imx7d-rpmsg device from DT!
Current U-Boot 2020.07, just checked it in git.toradex.com, still disables RPMSG unless M4 is started from U-Boot. See fdt_status_disabled(blob, off) call in my May 5 answer. You need to fix it first and only then expect RPMSG working starting M4 from Linux using imx_m4fwloader or rproc. iMX7 rproc as I understand got broken after FSL or someone else added support for iMX8. Yes, I made it working, but code is too dirty hack to share.
Thank you for the update. We are planning on running a small initialization app on M4 from U-Boot and loading the main app on m4 from Linux. But I will probably use your work around to prevent that from being an issue anyway.
see attached two diffs. One fixes rproc loader crash loading uninitialized elf segments or something like that. Another one makes MU unit mailboxes optional for rproc, like it was in older kernel. Without this patch I don’t know how to make both rpmsg and rproc happy sharing MU. Presence of mailbox-names property determines will rproc use MU or not. With patch applied you need something like that in DTB to make it working:
@CMR, perhaps try downloading again. Download is working from Edge on PC and Chrome on Android. If still not, then please ask Toradex why you can’t download them.
@Edward hi, Thanks for answering. My board is technexion imx7d-pico (with carrier board). In it I run Yocto dunfell with kernel 5.6.xx and libgpiod v 1.5.
I talk about libgpiod because my project is as follows: Press a button/Gpio on the breadboard on the linux side (a7) and turn on a led/Gpio that is being controlled on the freertos side (m4).
At first I thought of using RPmsg for this. I don’t know if it’s possible, as I don’t want to abandon the linux mainline due to libgpiod v1.5
Yes, RPMSG is the right way to establish communications between A7 running Linux and M4. gpiolib here is absolutely the least important thing. Since it seems you haven’t even launched any rpmsg demo, why are you asking about remoteproc??? Remoteproc has some issues using current kernel drivers. I know no way to to use it without driver mods. What mods I used I wrote above.
You should just go ahead to launch any rpmsg example, so that something on Linux side sends something using rpmsg to M4 side, and M4 recognizes it and reacts appropriately. Then you do your own protocol to command M4 from Linux to drive those LEDs.
Since you are using different kernel than we use with Toradex SOMs, it is up to you to figure out how to let your kernel enable RPMSG. It is up to you as well to figure out how to launch M4 firmware on your pico-imx7d.
@EdwardYoud said: why are you asking about remoteproc???
1) Because I didn’t find anything ready using RPmsg in mainline linux (I’ll talk below). 1.2) What do I need to do to show devices in /sys/class/remoteproc/ on my imx7d-pico with Yocto dunfell?
2) What version of linux are you using from Toradex in SOM?
As long as it is higher than 5.5 (because of libgpiod) or even a little lower) I ask you to pass me all the changes you made (here I use make menuconfig, where everything was already enabled from rpmsg and remoteproc) to be able to use RPmsg
no, you don’t need imx_rproc to make RPmsg working. RPmsg is what you need to establish communications between Linux and M4. Remoteproc is just one of the ways to launch M4 firmware.
1.2) for remoteproc you need imx_rproc driver and properly configured kernel device tree.
I am currently focusing my efforts on: OpenAmp-RPmsg in linux (Yocto-dunfell/mainline linux) part AND RPmsg-lite in Zephyr Part. But the meta-openamp layer is not yet ready for Yocto/dunfell and has stopped project progress:
If you can’t load M4 code to RAM in U-Boot, then your further DT file and dmesg are irrelevant.
Why don’t you just provide fatload command output here instead of 3rd party url???
=> fatload mmc 0:1 0x7F8000 hello_world.bin (with issue)
** Reading file would overwrite reserved memory **
Failed to load 'hello_world.bin
How big is your bin file? It should be <=32k to fit TCML.
Since you are using imx7d-pico, I think you are using different U-Boot, not the same like we are using on Colibri. Does mw.l fail as well writing to the same TCML area? If mw.l succeds then I don’t see why fatload could complain:
If it fails, perhaps try using OCRAM for code instead of TCML. Check if it’s possible with fatload load address 0x910000. mw.l shoudn’t complain as well: mw.l 0x910000 0x11223344
Hit any key to stop autoboot: 0
=> fatload mmc 0:1 0x910000 hello_world.bin
** Reading file would overwrite reserved memory **
Failed to load ‘hello_world.bin’
Why are you using BIN file instead of ELF? (BIN is only required for imxfwloader on Linux.) You may fatload ELF to anywhere in RAM, bootaux should copy required ELF segments to required target locations.