i.MX Processors Knowledge Base

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

i.MX Processors Knowledge Base

Discussions

Sort by:
Platform supported Kinara Ara2: imx95frdm imx8mpfrdm In this article, let's take imx8mpfrdm as example.   1. Create a Debian LSDK2512 release system for SD boot using the command below: $ ./flex-installer -i pf -d /dev/sdX $./flex-installer -b boot_IMX_arm64_lts_6.12.20.tar.zst -f firmware_imx8mpfrdm_sdboot.img -d /dev/sdX -m imx8mpfrdm -r rootfs_lsdk2512_debian_imx8mpevk.tar.zst note: if Debian base rootfs is used, please upgrade to full function Debian rootfs first. 2. Insert SD card on imx8mpfrdm and boot the system. Once the system has completed booting and you reach the kernel prompt: $ date -s "20260101 1100" // set date $ set proxy if needed 3. download rt-sdk-ara2.deb at: https://nxp1.sharepoint.com/:u:/r/teams/ext1081/Shared%20Documents/LF_v6.12.34/Debian%20Packages/r1.3/Package%201/rt-sdk-ara2.deb?csf=1&web=1&e=i4x1zD 4. Get the uiodma.ko kernel module for Debian from NXP. 5. Disable sleep when install package: $ systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target 6. Prepare the packages ARA2 needed: $ apt update $ apt install --reinstall -y libc6-dev $ ln -sf /usr/include/aarch64-linux-gnu/sys /usr/include/sys $ apt install -y python3-dev build-essential $ e2fsck -f /dev/mmcblk1p2 7. install Ara2 package: $ dpkg -i rt-sdk-ara2.deb The tail of successful log as follows: ... [ 783.892116] Adding 2097148k swap on /swapfile. Priority:-2 extents:17 across:35913728k SS /swapfile none swap sw 0 0 Swap file of 2G configured and enabled successfully. Enable rt-sdk-ara2.service service... Created symlink '/etc/systemd/system/multi-user.target.wants/rt-sdk-ara2.service' → '/etc/systemd/system/rt-sdk-ara2.service'. rt-sdk-ara2.service has been enabled. To stop the service from starting automatically on boot run: systemctl disable rt-sdk-ara2.service Post-install script completed successfully. 8. overwrite the kernel module: $ cp /root/uiodma.ko /root/kinara/rt_sdk_r1.3/art/linux/drivers/uiodma_cache_management/uiodma.ko $ systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target // re-enable sleep 9. reboot the system: $ reboot You will see the log as bellow: ... [ 57.855988] bash[1492]: +----------+-----------------+ [ 57.856188] bash[1492]: | Product | Current Version | [ 57.856297] bash[1492]: +----------+-----------------+ [ 57.856397] bash[1492]: | firmware | 1.1.2.0 | [ 57.856501] bash[1492]: | proxy | 1.3.0.0 | [ 57.856593] bash[1492]: | sysapi | 1.1.61.0 | [ 57.856695] bash[1492]: +----------+-----------------+ [ 57.856788] bash[1492]: [I:20260109:09:02:44:636750] [DeviceManager] [kinara_main_1479][DeviceManager] [ 57.856894] bash[1492]: +------------+--------------------+ [ 57.857019] bash[1492]: | Product | Supported Versions | [ 57.857124] bash[1492]: +------------+--------------------+ [ 57.857227] bash[1492]: | client_lib | 1.0.0.0 | [ 57.857327] bash[1492]: | client_lib | 1.1.1.0 | [ 57.857419] bash[1492]: | client_lib | 1.1.2.0 | [ 57.857525] bash[1492]: | client_lib | 1.3.0.0 | [ 57.857642] bash[1492]: | cnn_model | 2.0.0.0 | [ 57.857741] bash[1492]: | cnn_model | 2.1.0.0 | [ 57.857833] bash[1492]: | firmware | 0.5.2.0 | [ 57.857931] bash[1492]: | firmware | 1.1.2.0 | [ 57.858030] bash[1492]: | llm_model | 3.0.0.0 | [ 57.858129] bash[1492]: | llm_model | 3.1.0.0 | [ 57.858222] bash[1492]: | pci_driver | 1.0.4.0 | [ 57.858322] bash[1492]: | pci_driver | 1.0.6.6 | [ 57.858421] bash[1492]: | proxy | 0.8.0.0 | [ 57.858533] bash[1492]: | proxy | 0.9.0.0 | [ 57.858633] bash[1492]: | proxy | 1.1.1.0 | [ 57.858732] bash[1492]: | proxy | 1.3.0.0 | [ 57.858823] bash[1492]: +------------+--------------------+ [ 57.858930] bash[1492]: 2026-01-09 09:02:44 - Proxy launched succesfully [ 58.752944] bash[1514]: 2026-01-09 09:02:45 - Hardware bringup is done (1 device(s) configured) and proxy is launched successfully in the background. [ 58.755142] bash[392]: Logs saved in: /root/kinara/rt_sdk_r1.3/saved_logs/rt-sdk-ara2_logs.txt Now, enjoy your AI journey.
View full article
We are pleased to announce that Config Tools for i.MX v25.12 are now available. Downloads & links To download the installer for all platforms, please login to our download site via:  https://www.nxp.com/design/designs/config-tools-for-i-mx-applications-processors:CONFIG-TOOLS-IMX Please refer to  Documentation  for installation and quick start guides. For further information about DDR config and validation, please go to this  blog post. Release Notes Full details on the release (features, known issues...) DDR tool – Support for detecting multiple boards connected to the host system is added. – Automatic detection and selection of newly connected COM ports is implemented. – A Connection Test option to validate connectivity before running tests on the target is introduced. – i.MX 93 EVK LP4 configuration is added. – Training execution time information for i.MX 95 and i.MX 943 is included in logs. – Bus signal naming in the UI to align with i.MX pin naming conventions is consolidated. – CA bus values for i.MX943 with LPDDR4 are updated. – DRAM density calculation for i.MX 95 and i.MX 943 with LP4/4x is corrected. – Incorrect calculation of number of banks for i.MX 8M with DDR3L is fixed. – CS1_BNDs calculation for i.MX 91 is corrected. SerDes tool – i.MX 943 RFP support is added. System Manager – The ability to export user configuration in the CFG format is added. – Information about atomic resources to the Details view is added. – Generation and configuration of the config_fusa.h file is supported. – Resource and template assignment is improved. – Grayed-out resource assignments for unavailable configuration parameters in the Resources view are implemented. – Validation of configuration and user input is improved. – Problem decorators to the System and Boot view are added. – Design of the Boot and Details view is improved. – 5600 MT/s for i.MX 95 and i.MX 943 with LPDDR5 is enabled. – LP4/4x settings for DDR_SDRAM_ZQ_CNTL for i.MX 95 and i.MX 943 are updated. – Dual-rank configurations for i.MX 91 and i.MX 93 are updated. – LP4/4x configuration to support non-binary densities for i.MX 95 and i.MX 943 is updated. – Support for non-binary aligned LP4 density for i.MX 91 is added. – FRDM board support (LPDDR4X 15x15 at 4000 MT/s) for i.MX 95 is added. – Timing file discrepancies for i.MX 8MN with DDR3L are fixed. – Issue where changing PHY log level did not update generated code is fixed.
View full article
There are two ways to enable support for the imx95-19x19-evk board:   1.  Directly replace the flash.bin from the Yocto release. 1). depoly LSDK2512 on imx95-15x15-evk board which is supported in Debian LSDK2512     A:    $ flex-installer -i pf -d /dev/sdX -F     B: $ flex-installer -i auto -m imx95evk -d /dev/sdX   2). Download prebuild flash.bin for imx95-19x19-evk board from Yocto release:     A: download: https://www.nxp.com/webapp/sps/download/license.jsp? colCode=L6.12.20-2.0.0_MX95&appType=file1&DOWNLOAD_ID=null     B: Extract the downloaded file to obtain the flash.bin file: imx-boot-imx95-19x19-lpddr5-evk-sd.bin-flash_all   3). Overwrite flash.bin     $ sudo umount /dev/sdX; sudo dd if=imx-boot-imx95-19x19-lpddr5-evk-sd.bin-flash_all of=/dev/sdX bs=1024 seek=32   4). Insert the prepared SD card into the board and power it on. After entering the U-Boot prompt, set the boot command:     => setenv bootcmd "setenv bootargs 'root=/dev/mmcblk1p3 rw rootwait console=ttyLP0,115200 earlycon';ext2load mmc 1:1 0x90400000 Image;ext2load mmc 1:1 0x93000000 imx95-19x19-evk.dtb;booti 0x90400000 - 0x93000000"; saveenv     => reset   The Debian system will start automatically.   2. Build the BSP image using FlexBuild: 1).  clone the Flexbuild source code and apply the patch as attached. 2). build the bsp and boot images:       $ bld bsp -m imx95evk       $ bld boot -m imx95evk or download the pre-built image at: http://sun.ap.freescale.net/images/debian/lsdk2512/firmware_imx95evk_19x19_sdboot.img 3). install the image:       $ ./flex-installer -f firmware_imx95evk_sdboot.img -d /dev/sdX -m imx95evk -b boot_IMX_arm64_lts_6.12.20.tar.zst -r rootfs_lsdk2512_debian_imx95evk.tar.zst 4).  Insert the prepared SD card into the board and power it on. After entering the U-Boot prompt, run the following command to boot board:       u-boot=> bootflow scan -lb
View full article
The following is a guide on training a simple model in Pytorch and Tensorflow and deploying it on an application using the i.MX93 Ethos-65 Neural Processing Unit (NPU) and the i.MX95 eIQ Neutron NPU.
View full article
In some applications, we need to shift frequencies to avoid interference from certain frequencies, such as shifting to avoid Wi-Fi interference. The document is a guide for shifting DDR3 frequency.   The document uses the iMX8M Nano DDR3 as an example, but the process is the same for the iMX8M mini, iMX8M Plus, LPDDR4, etc. The main issue is resolving the DDR pll configuration. Before reading this article, we assume you are already familiar with using the DDR stress tool and DDR config rpa, or the DDR tool of the config tools.   pll_to_table_entry_rates.py can help you to find the settings. 
View full article
Hello everyone! In this document you'll find an example on how to build your Cortex-M33 code where some parts of the code runs from DDR, for this changes on ATF where the M33 core can visit DRAM in early stage. For this we will take advantage of RPROC framework, RPROC (Remote Processor Framework) is a Linux kernel and U-Boot subsystem that manages secondary, embedded processors (like Cortex-M cores), where we will use the A55 to load the M33 firmware. This will require changes on Linux device tree, ATF and M33 linker file. Requirements: Ubuntu 20.04 or later host PC i.MX93 QSB UUU Tool ARM GNU Toolchain (arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu) SDK package (SDK_25_09_00_MCIMX93-QSB) Prebuild Linux Image (LF_v6.12.34-2.1.0_images_IMX93EVK) ### Clone imx-mkimage, it is better to download the same version of the sw we are working with ### $ git clone https://github.com/nxp-imx/imx-mkimage -b lf-6.12.34-2.1.0 ### Decompress the GNU toolchain into a path in local disk, in this test would be /opt/ ### $ sudo tar -xvJf arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt ### Clone and build Uboot ### $ git clone https://github.com/nxp-imx/uboot-imx -b lf-6.12.34-2.1.0 $ cd uboot-imx $ make -j $(nproc --all) clean $ make -j$(nproc --all) ARCH=arm CROSS_COMPILE=/opt/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- imx93_11x11_evk_defconfig $ make -j $(nproc --all) ARCH=arm CROSS_COMPILE=/opt/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- ### Download and extract ELE firmware ### $ cd .. $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-2.0.3-286c884.bin $ chmod +x firmware-ele-imx-2.0.3-286c884.bin $ ./firmware-ele-imx-2.0.3-286c884.bin --auto-accept ### Optional if using i.MX FW ### $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.29-8741a3b.bin $ chmod +x firmware-imx-8.29-8741a3b.bin $ ./firmware-imx-8.29-8741a3b.bin --auto-accept ### Clone ATF ### $ git clone https://github.com/nxp-imx/imx-atf -b lf-6.12.34-2.1.0 $ cd imx-atf ### Modify ATF for the M33 to be able to access DDR ###   --- a/plat/imx/imx93/trdc_config.h +++ b/plat/imx/imx93/trdc_config.h struct trdc_mrc_config trdc_n_mrc[] = { { 0, 0, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for S400 DID0 */ { 0, 1, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for MTR DID1 */ - { 0, 2, 0, 0x80000000, 0x80000000, 0, true }, /* MRC0 DRAM for M33 DID2 */ + { 0, 2, 0, 0x80000000, 0x80000000, 1, true }, /* MRC0 DRAM for M33 DID2 */ { 0, 3, 0, 0x80000000, 0x80000000, 1, false }, /* MRC0 DRAM for A55 DID3 */ { 0, 5, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USDHC1 DID5 */ { 0, 6, 0, 0x80000000, 0x80000000, 0, false }, /* MRC0 DRAM for USDHC2 DID6 */ ### Build modified ATF ### $ make -j $(nproc --all) PLAT=imx93 bl31 CROSS_COMPILE=/opt/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- ### Modify linker file and build M33 code, in this example we are using hello world SDK example ### $ cd .. $ tar -xvzf SDK_25_09_00_MCIMX93-QSB.tar.gz $ cd SDK_25_09_00_MCIMX93-QSB/boards/mcimx93qsb/demo_apps/hello_world/armgcc --- a/boards/mcimx93autoevk/demo_apps/hello_world/armgcc/MIMX9352_cm33_ram.ld +++ b/boards/mcimx93autoevk/demo_apps/hello_world/armgcc/MIMX9352_cm33_ram.ld m_a55_suspend_ram (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000 m_data (RW) : ORIGIN = 0x20003000, LENGTH = 0x0001B000 m_rsc_tbl (RW) : ORIGIN = 0x2001E000, LENGTH = 0x00001000 + m_text_dram (RW) : ORIGIN = 0x8F000000, LENGTH = 0x00001000 + m_data_dram (RW) : ORIGIN = 0x8F001000, LENGTH = 0x00001000 } /* Define output sections */ . = ALIGN(4); } > m_text + .dram_text : + { + . = ALIGN(32); + *(.myDRAM) + . = ALIGN(32); + } > m_text_dram + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) .ARM.attributes 0 : { *(.ARM.attributes) } ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") + + .dram_data : + { + . = ALIGN(32); + *(.myDRAM_data) + . = ALIGN(32); + } > m_data_dram } a/boards/mcimx93autoevk/demo_apps/hello_world/hello_world.c +++ b/boards/mcimx93autoevk/demo_apps/hello_world/hello_world.c * Definitions ******************************************************************************/ +#define _RET_IP_ (unsigned long)__builtin_return_address(0) +#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) /******************************************************************************* * Prototypes /******************************************************************************* * Variables ******************************************************************************/ - +const char myString[] __attribute__((section(".myDRAM_data"))) = "Hello, World!"; /******************************************************************************* * Code ******************************************************************************/ +__attribute__ ((section(".myDRAM"))) +void Dram_test(void) { + PRINTF("Dram_test!!\r\n"); + + PRINTF("%s!!\r\n", myString); + + PRINTF("function %p\n",_THIS_IP_); +} + /*! * @brief Main function */ BOARD_BootClockRUN(); BOARD_InitDebugConsole(); - PRINTF("hello world.\r\n"); + PRINTF("hello world from DRAM.\r\n"); while (1) { ch = GETCHAR(); PUTCHAR(ch); + if(ch == 'a'){ + Dram_test(); + } } } $ export ARMGCC_DIR=~/gcc-arm-none-eabi-10.3-2021.10 $ export PATH=$PATH:~/gcc-arm-none-eabi-10.3-2021.10 $ ./build_release.sh ### Copy the resulting binaries to imx-mkimage ### $ cp ~/imx-atf/build/imx93/release/bl31.bin ~/imx-mkimage/iMX93 $ cp ~/uboot-imx/u-boot.bin ~/imx-mkimage/iMX93 $ cp ~/uboot-imx/spl/u-boot-spl.bin ~/imx-mkimage/iMX93 ### Copy i.MX firmware ### $ cd .. $ cp firmware-imx-8.29-8741a3b/firmware/ddr/synopsys/lpddr4_dmem_* ~/imx-mkimage/iMX93 $ cp firmware-imx-8.29-8741a3b/firmware/ddr/synopsys/lpddr4_imem_* ~/imx-mkimage/iMX93 $ cpfirmware-ele-imx-2.0.3-286c884/mx93a1-ahab-container.img ~/imx-mkimage/iMX93 ### Build the flash.bin using mkimage $ cd imx-mkimage $ make SOC=iMX93 flash_singleboot ### Clone, modify and build device tree for Linux to be able to use RPROC to load M33 Firmware ### $ git clone https://github.com/nxp-imx/linux-imx -b lf-6.12.34-2.1.0 --- a/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts +++ b/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts no-map; }; + dram: dram@20480000 { + reg = <0 0x8f000000 0 0x20000>; + no-map; + }; + rsc_table: rsc-table@2021e000 { reg = <0 0x2021e000 0 0x1000>; no-map; <&mu1 1 1>, <&mu1 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&dram>, <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; fsl,startup-delay-ms = <500>; status = "okay"; $ export ARCH=arm64 $ export CROSS_COMPILE=/opt/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- $ make imx_v8_defconfig $ make freescale/imx93-9x9-qsb.dtb Set SW for serial download on the QSB (0001), connect debug, download and power cables and turn on the QSB, for this test we will flash the demo image and just replace Linux device tree, flash.bin and M33 firmware into the QSB board. $ uuu -b sd_all flash.bin imx-image-full-imx93evk.wic Once it is done change SW to the respective bootmedia SD boot (0011) and boot the board and stop at uboot, to enter fastboot mode to load modified device tree and M33 firmware > fastboot 1 After this just run UUU tool on the host computer and fatload the files $ uuu -b fat_write imx93-9x9-qsb.dtb mmc 1:1 $ uuu -b fat_write hello_world.elf mmc 1:1 When the tool finish, stop fastboot mode by typing CTRL+C and then boot into Linux > boot Login with default password "root" and run the following commands to load M33 firmware $ root $ modprobe imx_rpmsg_tty $ cp /run/media/boot-mmcblk1p1/hello_world.elf /lib/firmware/ $ echo hello_world.elf > /sys/class/remoteproc/remoteproc0/firmware $ echo start >/sys/class/remoteproc/remoteproc0/state   Once done we can verify that the M33 firmware is running on DDR Hope everyone finds this useful! For any question regarding this document, please create a community thread and tag me if needed. Saludos/Regards, Aldo.
View full article
System Manager configuration via Config tools for i.MX. Create a new project, modify, view or edit available resources for your specific core. What will you learn How to create a new System Manager project Viewing and managing resources Creating and assigning templates Configuration of System Manager Tip: you can skip to a specific chapter   Introduction   New System Manager project     System Manager views   System Manager templates   Assigning a resource   Creating custom template   Exporting code     Download the tools here: https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/config-tools-for-i-mx-applications-processors:CONFIG-TOOLS-IMX   https://www.nxp.com/products/i.MX95
View full article
Legacy Interrupts in PCI have become a thing of the past in the PCI world, now that we have more efficient MSI interrupts in PCI Express, being used extensively across applications. However they are still used primarily for backward compatibility and boot-up support. Legacy Interrupts[INTx] used to be physical signals in PCI, however PCIe devices do not have physical INTx pins. So to support these legacy interrupts, PCIe emulates them logically. Almost like a virtual INTx mechanism. We shall see how these interrupts are realized in PCI Express, in such a way that developers/enthusiasts can get a hands-on following this guide. This blog has the following agendas:- 1. Why do we need to care about Legacy INTx style interrupts in PCIe? 2. System Overview 3. How are INTx legacy interrupts realized in PCIe? 4. Enabling and testing INTx emulation on iMX8MM
View full article
The purpose of this page is to provide supportive information for the selection of suitable camera modules that are supported by the i.MX 8M Plus (i.MX8MP). The guide is attached in this page. This helps customers evaluate project feasibility and integration aspects when considering i.MX 8MP SoCs for their products. It is strongly recommended to consult with NXP and the camera module vendor before finalizing the choice of the camera part number to ensure compatibility, availability, longevity, and pricing requirements. NXP Supported Sensors: Sensor Vendor Image Sensor Max Resolution Camera Module OmniVision OS08A20 8MP IMX-OS08A20 EXPI-OS08A20 OmniVision OV2775 2MP   Sony IMX219 8MP   Sony IMX477 12.3MP   Onsemi AR0144 1MP AR0144 Onsemi AR1335 13MP     Partner Enabled Sensors:   Partner Sensor Vendor Image Sensor Max Resolution ISP Tuning Camera Module Location FRAMOS Sony IMX415 8MP ✔   Munich, Germany/ Canada/USA Sony IMX662 2MP FSM:GO Sony IMX678 8MP Sony IMX900 3.2MP Sony IMX676 12MP Innowave Onsemi AR1335 13MP ✔   Austin, Texas, USA/Israel Sony IMX258 13MP Camera Modules Sony IMX219 8MP OmniVision OV5645 5MP   OmniVision OV2710 2MP   Basler Onsemi AR0821 8MP   Basler   Onsemi AR0521 5MP   Onsemi Onsemi AR0830 8MP   Image Sensors, Module available through Future Electronics   Onsemi AR0544 5MP Onsemi AR0821 8MP Onsemi AR0822 8MP Onsemi AR0145 1MP Onsemi AR0235 2MP Onsemi AR1335 13MP PHYTEC Onsemi AR0144 1MP     Germany/ China/India/ USA Onsemi AR0234 2.3MP   Onsemi AR0521 5MP   E-consystems Sony IMX662 2.4MP     Riverside, CA, USA/India Sony IMX900 3.2MP   Onsemi AR0234 2.3MP   CIS Corporation Sony IMX715 12MP ✔   Japan Sony IMX570 0.32MP   Onsemi AR0234CS 2MP   Sony Sony IMX500 12MP     Japan HINO Engg Sony IMX415 8MP ✔   Japan Sony IMX662 2MP   Leopard Imaging Sony IMX500 12MP ✔   Fremont, CA, USA/China   Note: CIS Corporation and HINO Engg currently only support customers in Japan market.
View full article
This article describes how to create a tiny rootfs based on BusyBox.   Test platform: i.MX 95 19x19 LPDDR5 EVK. The attached layer can be used with other platforms as well. Software: Linux BSP 6.12.34-2.1.0 Boot device: SD card   This article provides a custom meta-tiny-rootfs layer, to simplify the enablement. The layer: creates a custom distribution based on Poky, with no extra features creates a custom image based on BusyBox that only starts a terminal removes most of the machine features uses musl, instead of glibc   Using the default DISTRO=fsl-imx-wayland and core-image-minimal, the rootfs size is 800MB. Using the custom DISTRO=tiny-rootfs and core-image-tiny, the rootfs size reduces to 2.6MB.   How to? 1. Prepare the Yocto environment according to Section 3, 4, 5 in i.MX Yocto Project User's Guide. In the next commands, we'll assume the Yocto directory is imx-yocto-bsp, and the build directory is build. 2. Configure the build directory: cd ~/imx-yocto-bsp/ DISTRO=fsl-imx-wayland MACHINE=imx95-19x19-lpddr5-evk source ./imx-setup-release.sh -b build Note: The imx-setup-release.sh script accepts only Wayland distributions. We'll set the custom distro at the next step. 3. Set the custom distro. In the build directory, run: echo 'DISTRO = "tiny-rootfs"' >> conf/local.conf 4. Download the meta-tiny-rootfs archive, and extract it into the ~/imx-yocto-bsp/sources directory. cd ~/imx-yocto-bsp/sources tar -xvf meta-tiny-rootfs.tar.gz 5. Add the meta-tiny-rootfs layer to BBLAYERS: cd ~/imx-yocto-bsp/build bitbake-layers add-layer ../sources/meta-tiny-rootfs 6. Build the core-image-tiny image. bitbake core-image-tiny 7. Write the image on an SD card, and boot. You should be able to see a similar log: [ 6.183401] Run /sbin/init as init process init started: BusyBox v1.37.0 () starting pid 163, tty '': '/bin/mount -t proc proc /proc' starting pid 164, tty '': '/bin/mount -t sysfs sysfs /sys' starting pid 165, tty '': '/bin/mount -t devtmpfs devtmpfs /dev' mount: mounting devtmpfs on /dev failed: Resource busy starting pid 166, tty '': '/bin/mount -o remount,rw /' [ 6.246037] EXT4-fs (mmcblk1p2): re-mounted a5abac39-6c11-419f-97ef-86532e2616ad. starting pid 167, tty '': '/bin/mkdir -p /dev/pts' starting pid 168, tty '': '/bin/mount -t devpts devpts /dev/pts' starting pid 169, tty '': '/bin/mount -a' starting pid 170, tty '': '/sbin/swapon -a' starting pid 176, tty '': '/etc/init.d/rcS' starting pid 177, tty '/dev/ttyLP0': '/usr/sbin/ttyrun ttyLP0 /sbin/getty 115200 ttyLP0' Tiny Rootfs Operating System 1.0.0 imx95-19x19-lpddr5-evk /dev/ttyLP0 imx95-19x19-lpddr5-evk login:   How to add additional features?  If you want to add additional features to DISTRO_FEATURES, MACHINE_FEATURES, or IMAGE_FEATURES, please use the DISTRO_TINY_FEATURES, MACHINE_TINY_FEATURES and IMAGE_TINY_FEATURES variables. For example, to add bluetooth to MACHINE_FEATURES, add the following line in conf/local.conf. MACHINE_TINY_FEATURES = "bluetooth"   Note: If you need to add a package that requires the full libc (instead of musl), add the following in conf/local.conf: TCLIBC = "glibc"   These optimizations were inspired by this presentation: Honey, I shrunk the rootfs!
View full article
NETC presents itself as a multi-function PCIe Root Complex Integrated Endpoint (RCiEP) for easy software discovery of peripheral functions. As such, it contains multiple PCIe functions. PCIe RCiEP allows for easy software integration into OSes, which support PCIe but can be easily integrated as a simple platform device for RTOSes or bare metal implementations which do not support it. Configuration and control of ENETC(s) is implemented using a combination of registers and a command message interface implemented using descriptor rings in memory. Key goal of the DPDK is to provide a simple, complete framework for fast packet processing in data plane applications. Using the APIs provided as part of the framework, applications can leverage the capabilities of underlying network infrastructure. DPDK been prominent software in user space for networking applications pushes for eNetc driver to be written in user space. This document introduces overview of the NXP ENETC and how its driver is implemented and integrated into the DPDK. DPDK eNetc Driver support features Multi-queue supported, Packet type parsing, promisc, MAC exact filter table filtering, VLAN exact filter table filtering, Link status interrupt, Rx checksum offload, basic stats.
View full article
lspci output on iMX95EVK as PCIe RC Please take a good look at the snippet above. It is taken from the console of iMX95 after executing 'lspci' on a specific PCIe device[iMX8MM as PCIe EP] that gets enumerated as BDF[Bus Device Function] 01:00.0. This blog attempts to debunk the mystery revolving around the "Memory at " info of the lspci output. We will discuss what this address is, why it is used and its relevance in the PCIe world. This blog will focus on the following agendas: - 1. PCIe parent and child relationship in Linux Device Tree 2. What is CPU and PCIe address space and the need for address space translation?  3. Assigning resources to a PCIe device in Linux 4. How is address space translation carried out in Linux PCI Subsystem?   PCIe parent and child relationship in Linux Device Tree In the Linux device tree, PCIe parent and child relationship defines how PCIe Root Complex and Endpoints are positioned in the system. A PCIe parent node in the device tree represents a PCIe controller (Root Complex / Host-Bridge). Taking reference from a PCIe node present in the device tree source of imx95: -   pcie@4c300000 {                         compatible = "fsl,imx95-pcie";                         reg = <0x00 0x4c300000 0x00 0x10000 0x00 0x4c360000 0x00 0x20000 0x00 0x60100000 0x00 0xfe00000>;                         reg-names = "dbi\0atu\0config";                         #address-cells = <0x03>   …  }   pcie@4c300000 represents a Designware PCIe controller Root Complex which is a parent to the devices/bridge that will be connected to it. -- 'compatible' property identifies the specific PCIe controller. Its corresponding driver resides in drivers/pci/controller/dwc/pci-imx6.c -- 'reg' property specifies the memory mapped registers of the PCIe controller. Child nodes under PCIe RC represent devices on the PCIe bus. They can be fixed function devices like Wi-fi, Ethernet, NVMe or they can be PCIe bridges which further can have devices connected to it. Taking reference from 'arch/arm64/boot/dts/freescale/imx95.dtsi'   pcie_4ca00000: pcie@4ca00000 {                         compatible = "pci-host-ecam-generic";                         reg = <0x0 0x4ca00000 0x0 0x100000>;                         /* Must be 3. */              …              …              enetc_port0: ethernet@0,0 {                                 compatible = "fsl,imx95-enetc";                                 reg = <0x000000 0 0 0 0>;                                 clocks = <&scmi_clk IMX95_CLK_ENET>,                                          <&scmi_clk IMX95_CLK_ENETREF>;                                 clock-names = "ipg_clk", "enet_ref_clk";                                 nvmem-cells = <&eth_mac0>;                                 nvmem-cell-names = "mac-address";                                 status = "disabled";                         }; }   ethernet@0,0 is a PCIe device at bus 0, device 0, function 0. It is a child of PCIe RC which is memory mapped at 0x4ca00000   These child devices/bridges can either be dynamically discovered using PCI enumeration or they can be statically described in a device tree as seen in the device-tree snippet above in which "ethernet@0,0" entry statically tells the RC that the ethernet child device is connected to it. These child nodes are nested within a PCI parent node of the device tree as seen in the above example.   What is CPU and PCIe address space and the need for address space translation ? CPU address space is the system's physical memory map as seen by the processor. Example of CPU Physical Address Space viewed by Cortex-A55 on iMX95:-   Start address      End address    Module 0x48000000       0x4812FFFF    GIC Programming registers 0x4AA00000      0x4AAFFFFF    Neutron SRAM 0x4AC10000      0x4AC1FFFF    Camera domain block control 0x4E080000       0x4E08FFFF    DDR Controller This address space is kind of a global system view which is managed by system firmware/OS. These addresses are fixed by hardware-design. On the other hand, PCIe address space is local to PCI bus, managed by PCIe subsystem. The  addresses in this space are dynamically assigned. An example of PCIe address space that could look like the following:- 0x00000000   -    0x0FFFFFFF 0x10000000   -    0x1FFFFFFF 0x20000000   -    0x2FFFFFFF It is evident from the above explanation that CPU and PCIe address space operate in a separate and independent address domains. So the CPU cannot access the space of PCIe device unless a translation mechanism is in place. In one of the upcoming sections we will get to that as well but please spare a few minutes and ponder the question below:- Question : Why do you need separate address spaces for CPU and PCIe? Answer : One of the major reasons is modularity. We have separate spaces so that PCIe devices can be designed independently of the CPU architecture. Same card will work in different system. It will always have the flexibility of CPU remapping the PCIe space as and when needed. Also, different address spaces prevent devices to access arbitrary system memory. Based on the discussion in this section, it is evident that the PCIe address space is inherently different from the CPU address space and truth be told- it has its advantages. Therefore we need an entity to translate to/fro these address spaces. Here comes 'iATU' - Internal Address Translation Unit. On iMX SOCs, these hardware units are responsible for carrying out the address translation. These units are a part of Synopsys DesignWare PCIe Controller, providing programmable address translation windows for inbound and outbound transactions. For the readers who are uninitiated on the inbound and outbound transactions in pcie, please spare some time go through this technical blog - Understanding PCIe Outbound/Inbound windows with a use-case - NXP Community Note: - Address translation simply ensures that the CPU can access a PCIe device's memory and vice-versa.   Up until here, the readers must have got a basic picture of PCIe Address Translation. Before jumping into the nitty-gritty of this translation in the Linux PCI subsystem, let's discuss how the resources are assigned to a PCIe device.   Assigning resources to a PCIe device in Linux PCIe devices do not have a direct CPU instruction interface so they communicate through memory-mapped regions. Devices need memory for DMA operations or for MSI/MSIX interrupts. Different devices have different needs, so resources in PCIe could be MMIO where device registers are mapped or memory regions needed for DMA transfer. In linux, pci_assign_resource function of PCI subsystem is responsible for assigning IO and memory resources to the PCIe devices during system initialisation after PCIe devices are enumerated. It is called for all the devices on a PCI bus and based on the PCI devices' resource requirement, it assigns them. But how does the PCI subsystem in linux figure out what resources does the PCIe devices need ? - Every PCIe device has a configuration space defined by the PCIe specification. This includes   BAR[Base Address Registers] - To indicate what type of resource[IO/Mem] does  the device needs and the size of resource. Capabilities - To broadcast the device capabilities such as MSI Interrupts, ASPM low power states etc. Reading the BARs from the PCIe device will tell us what kind and size of the resources are needed by the device. // To determine the size of resource from the BAR of PCIe device:- Step-1: Write all 1's to the target BAR register. Step-2: Read back the value and clear the lower 4 bits (for a memory BAR) or 2 bits (for an I/O BAR), as these are status bits, not part of the size calculation Step-3 Perform Bitwise NOT on the value and add 1 to it. Step-4: The returned value indicates the size. Taking an example to understand this:- Let's assume that after reading back the value in Step-2 above, the BAR returns 0xFFFFF000. The lower 4 bits are already cleared. Step-3  we perform bitwise NOT on the value -> ~(0xFFFFF000) = 0x00000FFF Adding 1 to it : 0x00000FFF + 1 = 0x00001000 The obtained value 0x1000 = 4096 bytes indicates the size, meaning the BAR requires a 4KB memory region. // To determine the type of resource from the BAR of PCIe device:-   A Base Address Register (BAR) in PCI configuration space: Bit 0 → Resource type: 1 = I/O space 0 = Memory space For memory BARs: 00 = 32-bit 10 = 64-bit Bits 1–2 → Addressing type: Bit 3 → Prefetchable flag   Interpreting the value 0xFFFFF000, we get:-   Bit 0 = 0 → Memory space Bits 1–2 = 00 → 32-bit address Bit 3 = 0 → Prefetchable Upper bits → Base address (after masking)   pci_read_bases [drivers/pci/probe.c] in linux PCI subsystem is responsible to figure out the BAR memory size and type requirement during device enumeration. Needless to say, the above sequence of writing to the Endpoint's BAR and identifying the size and type of resource is executed on the PCIe RC. We have the following setup :- iMX95 <------> iMX8MM [RC]                     [EP] After PCIe RC has the size of the BAR that is required, the pci_assign_resource function allocates a memory range and then sets up translation from this memory range to the PCIe address space. we started this blog with a snippet, that shows the following lspci log:-   Referring to the above, please note that the RC driver has allocated: - 0x910100000 - 0x910110000 as the non-prefetchable memory address range, size=64KB The above memory address range is in the PCIe 1 Outbound space memory mapped on iMX95 SoC: -   The range 0x910100000 - 0x910110000 will be mapped to the PCIe address space of the End-point. This essentially means that if the cpu generates any address in between this range [inclusive of start and end-address], a PCIe TLP will be sent by the PCIe controller on the RC to the End-point on the bus. It could be a read or write to the memory of Endpoint. The address to write/read would be decided based on the address space translation. We shall discuss in-detail how this translation is exercised in the linux kernel in the next section.   How is address space translation carried out in Linux PCI Subsystem?   We start with some important questions: - Where is the range 0x910100000 - 0x910110000 specified ? How does the kernel know that it has to map the PCIe 1 Outbound space and not PCIe2 Outbound space or any other address space for that matter? -- Like all good things in Linux, this also starts with a 'device tree binary'. A dtb is passed by Uboot to the kernel so that it could get the hardware description of our board. Since we are using Torradex 's Verdin iMX95 EVK Board as Root Complex, this is the dtb that we are using - imx95-19x19-verdin-adv7535.dtb I will be attaching a working dtb with this blog so that the readers can use it if needed. This dtb includes - arch/arm64/boot/dts/freescale/imx95.dtsi Let's have a look at a particular pcie node of interest: -   'ranges' property is the answer to the questions that were asked in this section earlier.  - This property defines the address translation rules between the parent's address space and the child PCI address space.   Note:- This blog focuses only on 'ranges' property since it is relevant to our discussion. So the readers are advised to look elsewhere if they want to understand other device-tree properties of the PCIe node.  Let's decode the ranges property : It has the following format:- <PCI address><CPU address> <PCI size>      3 cells               2 cells             2 cells             So one entry will have 7 cells. In our dtsi we have 2 entries. 1st is for IO space translation and the 2nd is for Mem space translation. Referring to the second entry  :-   0x82000000 0x0 0x10000000 0x9 0x10000000 0 0x10000000 |------PCI address---------------| |-CPU address-| |---PCI size---|   The above gives us the following info: - MEM Space prefetchable <   0x82000000 0x00 0x10000000   // PCIe address: 0x10000000   0x09 0x10000000              // CPU/system address: 0x910000000   0x00 0x10000000              // Size: 256MB >;   0x82000000 = 1000 0010 0000 0000 0000 0000 0000 0000   Bits 31–30 (10) → Configuration space type: This indicates memory space. Bit 29 (0) → Non-relocatable Bit 28 (1) → Prefetchable = No (0 means non-prefetchable) Bits 27–24 (0010) → Address space type = Memory So, 0x82000000 means: PCI memory space Non-prefetchable 32-bit address space   Note:- For those of you wondering why lspci output mentions [size=64K] and dts says 256 MB. This is because 256MB is the maximum address space available for the PCIe devices. It is upto the Endpoint device, how large address space does it require and accordingly it gets allocated.     Similary IO space translation is also created from the 1st entry in 'ranges':- < 0x81000000 0x00 0x00 → PCI I/O address: 0x00000000 0x00 0x6ff00000 → CPU/system address: 0x6ff00000 0x00 0x100000 → Size: 1MB >;   we observe the same in the dmesg output of iMX95 Verdin EVK Linux console:-   So the MEM Space mapping is from CPU Address 0x910000000 - 0x091fffffff translated to PCIe Address 0x10000000 - 0x1fffffff It is only fair that we mention the driver that uses the 'ranges' property. The 'ranges' property get parsed in "pci_parse_request_of_pci_ranges -> devm_of_pci_get_host_bridge_resources" of "drivers/pci/of.c"     devm_of_pci_get_host_bridge_resources, for each range automatically  manages the memory allocated for these resources. It ensures that the resources are freed when the device is detached or the driver is removed. We have got the answer what & why is the cpu and pci address range the way it is. But in the lspci, you see 0x910100000 and not 0x910000000 which is what the intended start range is supposed to be as per the dtb. Why is that ? To answer this - we need to go back to the PCIe device enumeration. During PCIe enumeration, in the linux PCI driver the bar resources were determined like we had discussed earlier and then the PCI core driver may assign addresses keeping alignment requirements in mind that is why EP's BAR0 was assigned a PCI bus address as 0x10100000 with a 1MB[0x100000] offset from 0x10000000. And keeping the device tree pci translation window in mind:- 0x10100000 translates to 0x910100000 This translation doesn't happen on its own. Device tree binary just mentions the translation window specifics such as the CPU address space to translate to and the PCI address space to translate from. The actual translation is done via iATU. This is done in the dw_pcie_iatu_setup function of drivers/pci/controller/dwc/pcie-designware-host.c by creating the outbound window using dw_pcie_prog_outbound_atu function. Translation is configured on the RC successfully but there is still something missing. .. .. Inbound window !! Without an inbound window on the Endpoint i.e iMX8MM, the writes/reads to 0x910100000 would be meaningless. On iMX8MM we are using PCI Endpoint test driver which is quite popular in linux community and I would urge the readers to visit this page if they want more info - 9. PCI Endpoint Framework — The Linux Kernel documentation pci_epc_map_addr function in drivers/pci/endpoint/pci-epc-core.c creates inbound window by mapping PCI address [0x10100000] to physical address in EP's memory. That's how the reads and writes go through. If there's no Inbound window configured, something like this unfolds in case of read:-   So now everything is set up. Translation windows are configured in the PCI drivers and you are at linux console. The following sequence unfolds when the CPU issues a memory read:-   In case of memory writes:- The following happens on the Endpoint: - The beauty is that this entire translation happens transparently in hardware - your driver just reads/writes to the CPU address, and the PCI host controller handles all the translation automatically! -- How do we test the Address Translation ?   To test reads and writes, either we can make some changes in the driver itself or use devmem5 user-space binary. We are going to make minor driver side changes on iMX8MM and use devmem5 on the RC. iMX8MM is the PCIe Endpoint and we are using end-point test driver to configure it as such. If  you want to do the same, please follow this blog - Enabling PCIe End-point framework on iMX95 torradex board and iMX8MM EVK - NXP Community On the contrary if you want to make iMX95 as RC and iMX8MM Endpoint, feel free to follow this blog - How to configure iMX95EVK as PCIe Endpoint and test it using PCIe Endpoint Test Framework - NXP Community Two things we are going to do next: - 1. On iMX8MM EP, we are going to write some random values  in the drivers/pci/endpoint/pci-epf-core.c, make the following changes in pci_epf_alloc_space function: -     'space' is the virtual address and 'phys_addr' is the physical address that is contiguous. Please note that it is a crude way to test this translation. There are better ways to do it. Build the kernel after the changes and boot the board with it. Make iMX8MM an Endpoint using PCI Endpoint Test Framework. 2. On iMX95 Verdin EVK [PCIe RC], we are going to read the address 0x910100000 using devmem5 to verify that we can observe the same data on the RC.   That's it for today. This was a long blog and if you feel overwhelmed by the details, please feel free to drop in the DMs or comments so that I can try to make it easier. Until next time! Gaurav Sharma  
View full article
In this blog, we are going to discuss how we can configure iMX95EVK as PCIe Endpoint and test it using a RC which will be iMX8MM. Hardware Components iMX95EVK iMX8MM PCIe M.2 Key E Bridge Ethernet connectivity     Software Components Linux Factory 6.12.20 BSP linux-imx source code - https://github.com/nxp-imx/linux-imx/tree/lf-6.12.20-2.0.0 System setup Step -1 Flash the 6.12.20 BSP on the iMX95 EVK eMMC/SD card and boot with it. Step-2 Fetch linux-imx 6.12.20 source code from the github repo GitHub - nxp-imx/linux-imx at lf-6.12.20-2.0.0 Step-3 Make the following changes to arch/arm64/boot/dts/freescale/imx95-19x19-evk-pcie1-ep.dtso as per the following diff:-   diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk-pcie1-ep.dtso b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-pcie1-ep.dtso index a8e3bbc53894..d082688fc1c2 100644 --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk-pcie1-ep.dtso +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk-pcie1-ep.dtso @@ -11,12 +11,12 @@ &smmu {  };     -&pcie1 { +&pcie0 {         status = "disabled";  };   -&pcie1_ep { +&pcie0_ep {         pinctrl-names = "default"; -       pinctrl-0 = <&pinctrl_pcie1>; +       pinctrl-0 = <&pinctrl_pcie0>;         status = "okay";  };     As you can see, we are trying to enable 'End-point' mode on iMX95EVK's M.2 PCIe 0. The default dtb enables it for PCIe 1. Building the kernel will build this dtb from the dtso changes. Step-4 SCP the dtb to the board and rename it to "imx95-19x19-evk-pcie0-ep.dtb" to avoid confusion. Copy it to the location - /run/media/boot-mmcblk0p1/ Step-5 Boot the board with this DTB by changing the 'fdtfile' variable at Uboot. when the kernel boots up with this dtb, you will see the following pcie dmesg logs on the console through which you can verify if the changes have worked:-   root@imx95evk:~# dmesg | grep pcie-ep [    3.142123] imx6q-pcie 4c300000.pcie-ep: iATU: unroll T, 8 ob, 8 ib, align 4K, limit 1024G [    3.151767] imx6q-pcie 4c300000.pcie-ep: eDMA: unroll T, 4 wr, 4 rd root@imx95evk:~#   0x4c300000 is the address of pcie0 controller Step-6 Execute this script on iMX95EVK - 'conf_pcie0_ep' Step-7 Boot iMX8MM board with this dtb - imx8mm-evk.dtb Step-8 Executing 'lspci' on the iMX8MM, you will see the following output:- That's the iMX95EVK Endpoint that you see on the lspci output of iMX8MM RC.   The address space translation window is configured with the help of the info mentioned in  arch/arm64/boot/dts/freescale/imx8mm.dtsi If the readers want to make sense out of the translation window info mentioned in form of 'ranges' property of PCIe node, they can go through this article in which there is a detailed explanation of what is going behind the scenes - Demystifying the PCIe and CPU address space translation in Linux - NXP Community      
View full article
LSIO_GPIO0_IO0x toggling on i.MX8QM Issue customer met: Customer met LSIO_GPIO0_IO0x not toggling on i.MX8QM, they are working through the software on their board, part of that involves getting a few GPIO pins working. They have been using several GPIO pins for a while now, we have some simple toggles and some others where we bit bang i2c, all of those have worked fine. However, They have not been able to get 3 pins to either read or set successfully at all: LSIO_GPIO0_IO00 (SIM0_CLK) LSIO_GPIO0_IO01 (SIM0_RST) LSIO_GPIO0_IO02 (SIM0_IO) 1\ Reproduce on our i.MX8QM EVK board  a. Check the hardware connection Check the LSIO_GPIO0_IO00 (SIM0_CLK), LSIO_GPIO0_IO01 (SIM0_RST) and LSIO_GPIO0_IO02 (SIM0_IO) connection in our i.MX8QM EVK board. In the default design in NXP i.MX8QM EVK board, the pins SIM0_CLK, SIM0_RST and SIM0_IO connect to the SIM CARD on the base board.         b. To make these pins work as GPIO pins In the default pins mux, default pins mux on the SIM0, to make these pins work as GPIO, need to mux them to the GPIO functions. SIM0_CLK (SIM0_CLK)     SIM0_RST (SIM0_RST)   SIM0_IO (SIM0_IO)     c. In the source code change these pins mux to GPIO configuration: Defalt setting for these pins : linux-imx/arch/arm64/boot/dts/freescale/imx8qm-mek.dts at lf-6.12.y · nxp-imx/linux-imx · GitHub   pinctrl_sim0: sim0grp {                              fsl,pins = <                                            IMX8QM_SIM0_CLK_DMA_SIM0_CLK           0xc0000021                                            IMX8QM_SIM0_IO_DMA_SIM0_IO                 0xc2000021                                            IMX8QM_SIM0_PD_DMA_SIM0_PD               0xc0000021                                           IMX8QM_SIM0_POWER_EN_DMA_SIM0_POWER_EN                         0xc0000021                                            IMX8QM_SIM0_RST_DMA_SIM0_RST            0xc0000021                              >;               }; Linux dts should set them to GPIO0 functions:               IMX8QM_SIM0_CLK_LSIO_GPIO0_IO00 0xc0000021               IMX8QM_SIM0_RST_LSIO_GPIO0_IO01 0xc2000021               IMX8QM_SIM0_IO_LSIO_GPIO0_IO02 0xc0000021 Build the source code, download the images to board, test on the SIM pins to see if these pins can work or not. Test on the J45 pins 3,5,6.   Test the SIM_CLK as an example: Test commands in Linux echo 480 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio480/direction #output high echo 1 > /sys/class/gpio/gpio480/value #measure the PINs #output low echo 0 > /sys/class/gpio/gpio480/value #measure the PINs Found these pins can not toggling well. 2\ Go next further test and consideration Foud the SCU_GPIO0_00, SCU_GPIO0_01, SCU_GPIO0_02 are also configurate as GPIO function in the SCFW,  in the default setting for the SC_P_SCU_GPIO0_00is the function GPIO0_00 , and when setting the SIM0_CLK to GPIO0_00 function then the GPIO0_00 can not work normally. So if setting the SIM0_CLK as GPIO0_00 function, then we need to set the SC_P_SCU_GPIO0_00 this PIN to others function, so that no conflict of them. Even no use the pin SC_P_SCU_GPIO0_00 in hardware, we also need to set them to others function to avoid the conflict. SCU_GPIO Pins mux: SCU_GPIO0_00 (SCU_GPIO0_00)   SCU_GPIO0_01 (SCU_GPIO0_01)   SCU_GPIO0_02 (SCU_GPIO0_02)         Tested the PINs "SIM0_CLK, SIM0_IO, SIM0_RST" on iMX8QM MEK with base board. All of them works fine.  The key points are already listed. VDD_SIM0 power should be supplied (It is 3.3V on MEK from PF8100 LDO)   Linux dts should set them to GPIO0 functions:     IMX8QM_SIM0_CLK_LSIO_GPIO0_IO00 0xc0000021     IMX8QM_SIM0_RST_LSIO_GPIO0_IO01 0xc2000021     IMX8QM_SIM0_IO_LSIO_GPIO0_IO02 0xc0000021 The default IOMUX for PINs SC_P_SCU_GPIO0_00, SC_P_SCU_GPIO0_01, SC_P_SCU_GPIO0_02 should be changed from 0 to others.  Test on MEK, we used followed codes in SCFW board_init():     else if (phase == BOOT_PHASE_FINAL_INIT)     {         /* Configure SNVS button for rising edge */         SNVS_ConfigButton(SNVS_DRV_BTN_CONFIG_RISINGEDGE, SC_TRUE);           /* Init PMIC if not already done */         pmic_init();         pad_force_mux(SC_P_SCU_GPIO0_00, 2,             SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF);         pad_force_mux(SC_P_SCU_GPIO0_01, 2,             SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF);         pad_force_mux(SC_P_SCU_GPIO0_02, 2,             SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF);     }  Note: In SCFW, should also set SC_P_SCU_GPIO0_00, SC_P_SCU_GPIO0_01, SC_P_SCU_GPIO0_02 to other functions, because they are set to GPIO0_0x function default, if two PINs set to the same functions, such as SIM0_CLK_DMA pin and SCU_GPIO0_00 pin are set to GPIO0_00 together, the function will not work correctly.   Test commands in LInux: echo 480 > /sys/class/gpio/export echo 481 > /sys/class/gpio/export echo 482 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio480/direction echo out > /sys/class/gpio/gpio481/direction echo out > /sys/class/gpio/gpio482/direction #output high echo 1 > /sys/class/gpio/gpio480/value echo 1 > /sys/class/gpio/gpio481/value echo 1 > /sys/class/gpio/gpio482/value #measure the PINs, they are correct high  ( 3V ) #output low echo 0 > /sys/class/gpio/gpio480/value echo 0 > /sys/class/gpio/gpio481/value echo 0 > /sys/class/gpio/gpio482/value #measure the PINs, they are correct low ( 0V ) The test result is based on real measurement on iMX8QM MEK.    Note: 1\In customer's side If still not work, To confirm the issue, please suggest customer build SCFW with parameter "-m", then use followed commands to dump the IOMUX registers: md 0x41F80000 1 md 0x41F80040 1 md 0x41F80080 1 md 0x41F82140 1 md 0x41F82180 1 md 0x41F83000 1   The "md" command should run from SCFW debug UART, not linux/uboot UART. 2\Make sure the hardware in customer's side VDD_SIM0 power should be supplied .    
View full article
Some customer want to measure DSM power and do some customize in their own board. We supply the the AN13917 to customer already. But some customer also have some questions about it , so here give more details and test for it for customer will more clearly understand and use it. 1 i.MX 93 power mode overview The i.MX 93 supports the following power modes: Run mode: In this mode, the Cortex-A55 CPU is active and running. Some portions can be shut off for power saving. Low-power run mode: This mode is defined as a Low-power run mode with all external power rails on. In this mode, all unnecessary power domains (MIX) can be off. The AONMIX and internal modules, such as OSC24M/PLL, are an exception in this mode. The Cortex CPU in AONMIX handles all the computing and data processing. Cortex-A55 is powered down and DRAM can be in self-refresh/retention mode. Idle mode: This mode is defined as one that a CPU can enter automatically when no threads are engaged, and no high-speed devices are in use. CPU can be put into a power-gated state, but with L3 data retained, DRAM, and bus clocks are reduced. Most of the internal logic is clock-gated; yet is still powered. In this mode, all the external power from PMIC remains the same, and most IPs remain in their state. Therefore, the interrupt response in this mode is quick compared to the Run mode. Suspend mode: This mode is defined as the most power-saving mode since it shuts off all the clocks and all the unnecessary power supplies. In this mode, the Cortex-A55 CPU is fully power gated, all internal digital logic, and the analog circuits that can be powered down are off, and all PHYs are power gated. VDD_SOC(and related digital supply) voltage is reduced to the "Suspend mode" voltage. Compared to Idle, this mode takes a longer time to exit, but it also uses far less energy. BBSM mode: This mode is also called RTC mode. In this mode, to keep RTC and BBSM logic alive, only the power for the BBSM domain remains on. Off mode: In this mode, all power rails are off. 2 Measure the power consumption of the system in the DSM( Deep Sleep Mode) The use case is based on the Suspend mode, which implies the following: CA55 cluster is OFF • MEDIAMIX is OFF • NICMIX is OFF • WAKEUPMIX is OFF • PLL is OFF • 24 M OSC is OFF PMIC is in STBY mode Download the demo images from website: Download the AN13917SW.zip file, upzip it. Copy the uuu and imx93-11x11-evk-dsm.dtb to demo images path. Download the images to board: .\uuu.exe -b emmc_all .\ imx-boot-imx93-11x11-lpddr4x-evk-sd.bin-flash_singleboot  .\imx-image-full-imx93evk.wic To measure the power consumption of the system in the DSM, the steps are as follows: Boot the Linux image with imx93-11x11-evk-DSM.dtb. System boot up with the default dtb, when system boot up change it to the imx93-11x11-evk-DSM.dtb, using the following commends: setenv fdtfile imx93-11x11-evk-dsm.dtb saveenv boot To put the system into the Suspend (Deep sleep) mode, run the following command: echo mem > /sys/power/state Measure the power and record the results. About the BCU Tool: BCU (Board Remote Control Utilities):BCU is a software specially designed to control boards/platforms that support remote control. It provides functions such as on/off key operation, board reset, setting boot mode, controlling GPIO, and power measurement through the debug cable. ------->Remote Control function: $ sudo ./bcu reset sd [-board=xxx] version bcu_1.0.158-0-gdb0a8e5 Auto recognized the board: imx8dxlevk set reset high successfully set onoff high successfully set ft_reset high successfully ENABLE remote control set sd_pwr high successfully set sd_wp high successfully set sd_cd high successfully set boot mode successfully set bootmode_sel low successfully Set ALL sense resistances to smaller ones rebooting... reset successfully done -------->Power measurement function: $ sudo ./bcu monitor -hz=1 [-board=xxx] Here for the power measurement function support the boards have power measurement function. This is the example for the power measurement for the i.MX93 EVK board: 1\Download the BCU tool Releases · nxp-imx/bcu Download the bcu_1.1.100 to Windows 2\Connect the i.MX93 EVK board to Windows PC 3\Open the teminal in the Windows PC C:\Users \Desktop>bcu.exe monitor -board=imx93evk11b1 -hz=1 Use the bcu.exe monitor -board=imx93evk11b1 -hz=1 Make sure the board version is proper, current board is B1 version, so the board name is imx93evk11b1. 4\Run the command in the PC : For others mode test can refer to the BCU.pdf file: https://github.com/nxp-imx/bcu/releases/download/bcu_1.1.100/BCU.pdf Note: To make sure the board version are proper with the related command: bcu.exe monitor -board=imx93evk11b1 -hz=1 For the i.MX93 SOM B2 version Board can use the above command. If the board version is old, such as use the i.MX93 SOM B, here you need to use the command: bcu.exe monitor -board=imx93evk11 If using the bcu.exe monitor -board=imx93evk11b1 the test result are not for this board, here can use the ./bcu eeprom -w -board=imx93evk11 to write the eeprom for the imx93evk11. Using the bcu eeprom -r -board=imx93evk11 see the present status. If we met the problem as bellow we need to check and write to the eeprom again. Measure the power in the DSM mode on the i.MX93 board with SOMB2(board name with the i.mx93evk11b1): old EVK imx93evk11 use a 20m Ohms sensing resistor new EVK imx93evk11b1 use a 5m Ohms sensing resistor For the the i.MX93 board with SOM B Measure the power in the DSM mode on the i.MX93 board with SOMB2 result, use the small and larger range test: Measure the power in the DSM mode on the i.MX93 board with SOMB result: Using the command bcu.exe monitor -board=imx93evk11 -hz=1 3 Questions from customer a.The diff/patch between imx93-11x11-evk.dts and imx93-11x11-evk-dsm.dts If customer use the Linux kernel version: L6.1.55 version BSP, they need to use the imx93-11x11-evk-dsm.dtb we supply. And if using the newer than it and newest BSP in our website, they do not need to change the dtb to the and imx93-11x11-evk-dsm.dtb, just using the imx93-11x11-evk.dts will be OK, as for the Atf  also add the has_wakeup_irq = true;   And in the default imx93-11x11-evk.dts already support the  linux-imx/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts at lf-6.12.y · nxp-imx/linux-imx · GitHub   So customer and directly use on their products. b. NXP i.MX93 EVK DSM power measurement, the GROUP_SOC_FULL  are some difference from our AN. As different chips may show slight differences in static power consumption(SS TT FF) due to process corner variations.  
View full article
This article describes how to speed-up the Linux boot time on i.MX 6ULZ to under 2s. Software: Linux BSP 6.12.20-2.0.0 Boot device: SD card The attached imx6ulz-fast-boot.tar.gz archive contains a series of patches which reduces the boot time of the i.MX 6ULZ to ~1.9s. What you'll find in the archive: U-Boot patches: Set the BOOTDELAY to 0 in U-Boot Increase the CPU frequency from 396MHz to 792MHz Add quiet to the kernel bootargs, to suppress the kernel's output during boot Kernel patches: Trim down the kernel to create a minimal version Use LZ4 compression type for the kernel image Minimal rootfs based on BusyBox How to? 1. Prepare the Yocto environment according to Section 3, 4, 5 in i.MX Yocto Project User's Guide. Version 6.12.20-2.0.0, for other versions, you may need to make adjustments. 2. Unzip the imx6ulz-fast-boot.tar.gz archive in the sources directory of your Yocto environment just created. cd ~/imx-yocto-bsp/sources tar -xvpzf imx6ulz-fast-boot.tar.gz -C . 3. Remove additional machine features. Add the configuration below in your conf/local.conf: MACHINE_FEATURES:remove = "\ optee \ alsa \ touchscreen screen \ wifi bluetooth \ bcm4339 bcm43455 \ nxp8987-sdio nxpwifi-all-sdio \ rtc qemu-usermode"  4. Build the image. bitbake core-image-busybox The resulted core-image-busybox-imx6ulz-14x14-evk.rootfs.wic should have ~38M. 5. Write the image on an SD card, and boot. It should boot under 2s from reset to prompt. If you are connected to the serial port of the board, press any key continuously to stop in U-Boot.
View full article
As we haven't provided a guide with steps that implement the Linux OS encryption and signature for i.MX9x products so far. So, the document provides the steps for that. For details related to how to encrypt and sign a bootloader image, please have a reference to This Guide 
View full article
This article describes how to enable the GPIO support in SPL for i.MX 93 and how to use the associated library. Available GPIO banks Bank Registers' Base Address GPIO1 0x47400000 GPIO2 0x43810000 GPIO3 0x43820000 GPIO4 0x43830000   Software Tests performed using the LF6.12.20-2.0.0 BSP, but should work similarly in other versions.   Enable the GPIO support in SPL Enable the CONFIG_SPL_GPIO through menuconfig. Configure the GPIO pin Make sure the chosen GPIO pin is not used by any other peripheral, by checking U-Boot's device tree (example: imx93-11x11-evk.dts and its included files). If used, disable the conflicting peripheral in the device tree. To identify the exact macro associated to the GPIO functionality, please check the arch/arm/dts/imx93-pinfunc.h file.  Example 1: Use an available GPIO pin (e.g. GPIO2_IO05) This pin is not used by other peripheral, so there is nothing to disable.  To use the pin with the GPIO functionality, the following pin muxing must be added in the iomux node of the imx93-11x11-evk.dts file (located in dts/upstream/src/arm64/freescale/😞 😞 pinctrl_hog: hoggrp { fsl,pins = < MX93_PAD_GPIO_IO05__GPIO2_IO05 0x51e >; }; Note: 0x51e represents the value you want in the PAD register (SW_PAD_CTL_PAD_GPIO_IO05). You may configure it as you want.  Example 2: Use the XSPI1_TXC pin as GPIO (GPIO1_IO12) In our BSP, by default, this pin is used by the SAI1 peripheral. To use this pin as GPIO, SAI1 must be disabled in device tree. &sai1 { status = "disabled"; }; To use the XSPI1_TXC pin with the GPIO functionality, the following pin muxing must be added in the iomux node of the imx93-11x11-evk.dts file (located in dts/upstream/src/arm64/freescale/😞😞 pinctrl_hog: hoggrp { fsl,pins = < MX93_PAD_SAI1_TXC__GPIO1_IO12 0x51e >; }; Include the correct header files In the file you want to use the GPIO, include the following headers: #include <asm/arch-mx7ulp/gpio.h> #include <asm-generic/gpio.h> Define the GPIO To define the GPIO's handle, use the IMX_GPIO_NR(bank, index) macro. index = The pin number within the bank. bank = The GPIO bank number, mapped as follows (due to the way they are placed in memory): GPIO Bank bank value for IMX_GPIO_NR GPIO1 4 GPIO2 1 GPIO3 2 GPIO4 3 Example 1: Compute the handle for GPIO2_IO05 #define TIMED_GPIO IMX_GPIO_NR(1, 5) Example 2: Compute the handle for XSPI1_TXC (GPIO1_IO12) #define TIMED_GPIO IMX_GPIO_NR(4, 12)   Read the GPIO pin gpio_request(TIMED_GPIO, "timed_gpio"); gpio_direction_input(TIMED_GPIO); int val = gpio_get_value(TIMED_GPIO); printf("GPIO value is %d\n", val);   Write the GPIO pin gpio_request(TIMED_GPIO, "timed_gpio"); // set the pin as output and make it high gpio_direction_output(TIMED_GPIO, 1);   The driver used is drivers/gpio/gpio-uclass.c.
View full article
Background : Some customer wants to know the DRAM's MR register value. But, For now, we do not have any documentation or binary to complete this. So, this article aim to show how to read this register.   Hardware environment : i.MX8ULP EVK board Software environment : uboot-imx : lf_v2024.04   1. The related registers information are as following:   DENALI CTL 165 [READ MODEREG[24:8]] Read the specified memory mode register from specified chip when start bit set. Bits (7:0) define the memory mode register and bits (15:8) define the chip select. Set bit (16) to 1 to trigger.   DENALI CTL 166 [PERIPHERAL MRR - DATA[31:0]] Data and chip returned from memory mode register read requested by the READ MODEREG parameter. Bits (7:0) indicate the read data and bits (15:8) indicate the chip. READ-ONLY   2. Test result :         Type the below command: mrr <chip_select MR_register>  Like the below picture, when type the mrr 0 c, it means the chip select is 1 and the MR register is MR12, then the value of MR12 register can be output , is 0x1c.     Note : When read the MR register, must make sure the register has read right. Because most of MR register only have write right. you can check about it on JDEC spec document.   If you want to get the test binary file, please contact to me, i will send it to you.
View full article
i.MX8MP and i.MX95 both support USB3.0. In EVK board, USB download pin is USB3.0 with Type-C.  While in other boards, they may delete CC logic design PTN5110, or use USB2.0 signals instead. This document describes how to modify U-Boot to support a design without PTN5110 when using the uuu tool to download.
View full article