[8MP]Workaround for running UART with SDMA enabled on Cortex M7 in parallel of Linux on A53

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[8MP]Workaround for running UART with SDMA enabled on Cortex M7 in parallel of Linux on A53

[8MP]Workaround for running UART with SDMA enabled on Cortex M7 in parallel of Linux on A53

danielchen_1-1752057653400.png

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: 

1  Hardware requirements

2  Software Requirements

3  Modification in application

     3.1 Pin changes

    3.2 Clock changes

    3.3 Application specific changes

    3.4 Memory Region Control change

4  ATF changes

    4.1 Download ATF source and change it 

    4.2 build ATF

5   U-BOOT change

    5.1 build u-boot

    5.2 make imx-boot image by using imx-mkimage

    5.3 flash imx-boot image into i.MX 8MP EVK board

6  Running and Debugging

    6.1    Debugging Cortex-M while Cortex-A is in U-BOOT

    6.2   Debugging Cortex-M while Cortex-A is in Linux

7  Summary

 

1  Hardware requirements

 

-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.

 

danielchen_2-1752054416539.png

1752053262947-1.jpg

 

 

2  Software Requirements

 

SDK_25_06_00_EVK-MIMX8MP

This package can be download from https://mcuxpresso.nxp.com/

Next I will describe the detailed steps.

 

3  Modification in application

 

 

3.1 Pin changes

 

evkmimx8mp_iuart_sdma_transfer\pin_mux.c

danielchen_7-1752044305211.png  

3.2 Clock changes

 

evkmimx8mp_iuart_sdma_transfer\clock_config.c

In function BOARD_BootClockRUN

 

danielchen_8-1752044477575.png

 

3.3 Application specific changes

 

evkmimx8mp_iuart_sdma_transfer\board.h

danielchen_9-1752044702641.png

 

   app.h

danielchen_5-1752043367388.png

 

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.

danielchen_0-1753094438216.png

 

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.

3.4 Memory Region Control change

 

hardware_init.c

In function BOARD_InitHardware

danielchen_6-1752044211920.png

.....

Then compile the application, the output are  iuart_sdma_transfer.bin and iuart_sdma_transfer_cm7.elf

 

4  ATF (ARM Trust Firmware)changes

 

4.1  Download ATF source and Change it 

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

danielchen_0-1752050705989.png

We need to assign UART3 to domain 1 so Cortex M7 can access

danielchen_0-1752048818019.png

 

4.2 build ATF 

 

 

$ 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

 

5   U-BOOT change

 

5.1 Download and build u-boot

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

 

5.2 make imx-boot image by using imx-mkimage

 

My work folder

danielchen_0-1754124684342.png

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.

5.2.1  Download source :

$ git clone https://github.com/nxp-imx/imx-mkimage.git -b lf-6.12.20-2.0.0

 

5.2.2  Copy and rename mkimage from u-boot/tools/mkimage to imx-mkimage/iMX8M/mkimage_uboot.

$ cp uboot-imx/tools/mkimage imx-mkimage/iMX8M/mkimage_uboot

 

5.2.3 Copy u-boot-spl.bin from u-boot/spl/u-boot-spl.bin to imx-mkimage/iMX8M/

$ cp uboot-imx/spl/u-boot-spl.bin imx-mkimage/iMX8M/

 

5.2.4 Copy u-boot-nodtb.bin from u-boot/u-boot-nodtb.bin to imx-mkimage/iMX8M/

$ cp uboot-imx/u-boot-nodtb.bin imx-mkimage/iMX8M/

 

5.2.5 Copy  imx8mp-evk.dtb from u-boot/arch/arm/dts/ to imx-mkimage/iMX8M/.

$cp uboot-imx/u-boot.dtb imx-mkimage/iMX8M/imx8mp-evk.dtb

 

5.2.6 Copy bl31.bin from Arm Trusted Firmware (imx-atf) to imx-mkimage/iMX8M/

$ cp imx-atf/build/imx8mp/release/bl31.bin imx-mkimage/iMX8M/

 

5.2.7 Copy the LPDDR4 Training Firmware

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/

  • 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 

 

$ 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/

 

 5.2.8 Copy firmware/hdmi/cadence/signed_hdmi_imx8m.bin from the firmware-imx package to 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

danielchen_0-1753024778543.png

 

 

5.2.9 Build the bootable image

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

 

5.3 flash imx-boot image into i.MX 8MP EVK board

 

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). 

 

6  Running and Debugging

 

Download the application (iuart_sdma_transfer.bin and iuart_sdma_transfer_cm7.elf) to /run/media/boot-mmcblk1p1

danielchen_0-1753100235298.png

 

6.1    Debugging Cortex-M while Cortex-A is in U-BOOT

 

$ 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

danielchen_0-1756102850400.png

 

6.2   Debugging Cortex-M while Cortex-A is in Linux

 

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.

 

7  Summary

 

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

 

 

 

 

Labels (1)
No ratings
Version history
Last update:
2 weeks ago
Updated by: