This post contains a guide of how to use SDMA1 on Cortex M7 in parallel of Linux on A53.
For i.MX 8M Plus, SDMA1 is a general-purpose DMA engine which can be used by low speed peripherals including UART, SPI and other peripherals. But some customers found issues when they are using SDMA1 on M7 core in parallel of Linux on A53. For example, if you try to run the sdma_uart_transfer example on the i.MX8M Plus EVK, the example works correctly when interfacing through the JLink debugger. However, you will find that you can not run it from both the remoteproc interface and U-Boot. It exits without error from the UART_SendSDMA function, but the callback is never called and it seems to hang waiting for the information to be sent.
On the i.MX 8MP EVK board, uart4 is used for Cortex-M7 core. This article tries to provide an example to establish communication using UART3 and SDMA1 on the i.MX 8MP EVK, while Linux is running on Core A53. This example is based on sdma_uart_transfer demo. The steps are verified with i.MX Linux 6.12.20_2.0.0 release and SDK_25.06.00. The software is compiled on an Ubuntu 22.04 host machine.
This article is structured as follows:
3.3 Application specific changes
3.4 Memory Region Control change
4.1 Download ATF source and change it
5.2 make imx-boot image by using imx-mkimage
5.3 flash imx-boot image into i.MX 8MP EVK board
6.1 Debugging Cortex-M while Cortex-A is in U-BOOT
6.2 Debugging Cortex-M while Cortex-A is in Linux
-PC Host with MCUXpresso for VS Code installed
-i.MX 8M Plus EVK (i.MX 8M Plus Power Evaluation Kit | NXP Semiconductors)
-12V power supply
-Micro USB Cable
-J-Link Debug Probe.
-USB To TTL( serial ) Converter
connect J21 (Pin6_GND Pin8_UART3-TXD Pin10_UART3-RXD) to Host PC via a USB to TTL converter.
SDK_25_06_00_EVK-MIMX8MP
This package can be download from https://mcuxpresso.nxp.com/
Next I will describe the detailed steps.
evkmimx8mp_iuart_sdma_transfer\pin_mux.c
evkmimx8mp_iuart_sdma_transfer\clock_config.c
In function BOARD_BootClockRUN
evkmimx8mp_iuart_sdma_transfer\board.h
app.h
Till now, we have completed all the changes for change uart4 to uart3.
Compile , and debug with J-LINK, we can get the correct result.
Board receives 8 characters then sends them out.
However, if we try to load code on Cortex-M from U-Boot or Linux, we can not get the expected results. Below steps is a workaround to fix this issue.
hardware_init.c
In function BOARD_InitHardware
.....
Then compile the application, the output are iuart_sdma_transfer.bin and iuart_sdma_transfer_cm7.elf
The RDC configuration in default BSP assign UART2 to domain 0 for A53, and Domain 0 can read/write RDC, and Domain 1 (M7) only can read it.
$ git clone https://github.com/nxp-imx/imx-atf -b lf-6.12.3-1.0.0
GitHub - nxp-imx/imx-atf: i.MX ARM Trusted firmware
plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
We need to assign UART3 to domain 1 so Cortex M7 can access
$ git clone https://github.com/nxp-imx/imx-atf -b lf-6.12.3-1.0.0
$ cd imx-atf
$ source /opt/fsl-imx-xwayland/6.12-walnascar/environment-setup-armv8a-poky-linux
$ export ARCH=arm64
$ unset LDFLAGS
$ make PLAT=imx8mp bl31
This builds the bl31.bin binary, the location is :
build/imx8mp/release/bl31.bin
please refer to chapter 4.5.13 How to build imx-boot image by using imx-mkimage ,
$ git clone https://github.com/nxp-imx/uboot-imx -b lf_v2025.04
$ cd uboot-imx/
$ source /opt/fsl-imx-xwayland/6.12-walnascar/environment-setup-armv8a-poky-linux
$ export ARCH=arm64
$ make distclean
$ make imx8mp_evk_defconfig
$ make
The compiled u-boot.bin location
uboot-imx/u-boot.bin
My work folder
The following steps allow you to build the bootable image for i.MX 8M Plus EVK, there are 9 files needed to generate a bootable image:
├── u-boot-spl.bin
├── u-boot-nodtb.bin
├── imx8mp-evk.dtb
├── bl31.bin
├── signed_hdmi_imx8m.bin
├── lpddr4_pmu_train_1d_dmem_202006.bin
├── lpddr4_pmu_train_1d_imem_202006.bin
├── lpddr4_pmu_train_2d_dmem_202006.bin
└── lpddr4_pmu_train_2d_imem_202006.bin
Once you have the nine files , use imx-mkimage tool.
$ git clone https://github.com/nxp-imx/imx-mkimage.git -b lf-6.12.20-2.0.0
$ cp uboot-imx/tools/mkimage imx-mkimage/iMX8M/mkimage_uboot
$ cp uboot-imx/spl/u-boot-spl.bin imx-mkimage/iMX8M/
$ cp uboot-imx/u-boot-nodtb.bin imx-mkimage/iMX8M/
$cp uboot-imx/u-boot.dtb imx-mkimage/iMX8M/imx8mp-evk.dtb
$ cp imx-atf/build/imx8mp/release/bl31.bin imx-mkimage/iMX8M/
Download LPDDR Training Firmware
cd ~/work
wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.16.bin
chmod +x firmware-imx-8.16.bin
./firmware-imx-8.16.bin
copy below files from firmware/ddr/synopsys of the firmware-imx package to imx-mkimage/iMX8M/
$ cp firmware-imx-8.16/firmware/ddr/synopsys/lpddr4_pmu_train_1d_dmem_202006.bin imx-mkimage/iMX8M/
$ cp firmware-imx-8.16/firmware/ddr/synopsys/lpddr4_pmu_train_1d_imem_202006.bin imx-mkimage/iMX8M/
$ cp firmware-imx-8.16/firmware/ddr/synopsys/lpddr4_pmu_train_2d_dmem_202006.bin imx-mkimage/iMX8M/
$ cp firmware-imx-8.16/firmware/ddr/synopsys/lpddr4_pmu_train_2d_imem_202006.bin imx-mkimage/iMX8M/
$ cp firmware-imx-8.16/firmware/hdmi/cadence/signed_hdmi_imx8m.bin imx-mkimage/iMX8M/
The folder structure after copying all the necessary files
run make SOC=iMX8MP flash_evk to generate imx-bootimage.
$ cd imx-mkimage
$ make SOC=iMX8MP flash_evk
The compiled file is flash.bin and its location
iMX8M/flash.bin
In order to flash the imx-boot image, please follow the following steps
-copy uuu.exe and flash.bin in a folder
-change the board's SW4 (boot mode) to 0001 to enter serial download mode
uuu.exe -b emmc flash.bin
uuu.exe -b emmc flash.bin
-power off the board, change SW4 to switch the board back to 0010 (eMMC boot mode).
Download the application (iuart_sdma_transfer.bin and iuart_sdma_transfer_cm7.elf) to /run/media/boot-mmcblk1p1
$ fatload mmc 2:1 0x48000000 iuart_sdma_transfer.bin
$ cp.b 0x48000000 0x7e0000 30000;
$ bootaux 0x7e0000
$ fatload mmc 2:1 0x48000000 iuart_sdma_transfer2.bin
$ cp.b 0x48000000 0x7e0000 30000;
$ bootaux 0x7e0000
From M7 console, we can see the output
u-boot=> setenv fdtfile 'imx8mp-evk-rpmsg.dtb'
u-boot=>run prepare_mcore
u-boot=>boot
u-boot=> setenv fdtfile 'imx8mp-evk-rpmsg.dtb'
u-boot=>run prepare_mcore
u-boot=>boot
Linux system boot up:
echo /run/media/boot-mmcblk2p1/iuart_sdma_transfer_cm7.elf > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state
Then we can see the output from M7 console.
This is a workaround to run UART with SDMA1 enabled on Cortex-M7, and Linux running on Cortex-A53 in parallel. In order to do that, we need to modify the ATF, and U-BOOT, and application. With the above modifications, I can get the expected results.
References:
1. UG10163: i.MX Linux User's Guide Rev LF6.12.20_2.0.0--26 June 2025