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:
some industry customer to use i.MX8MM will use RMII to link the 100Mhz ethernet phy and wish to use our i.mx8mm output 50Mhz reference clock to external phy to save a crystal, this doc and patch explain how to support it. SW: Linux BSP 5.10.17. HW: i.MX8MM LPDDR/DDR EVK board. 中文版本为一个完整的如何支持一个100Mhz以太网PHY  
View full article
1. Intro   This document contains instructions to run run the SAI low power audio demo on the i.MX 8M Plus EVK. Here, the  RPSMG to allows audio to be passed from the A53 cluster running Linux to the M7 core. The latter controls the on board WM8960 audio codec,  which is connected to a 3.5 mm audio jack that allow us to play music using headphones. I will show the necessary steps to make the demo work and will add some GStreamer examples to demonstrate the demo's capabilities.   TBD: update this with a nice diagram that depicts the A53 and M7 RPMSG channel. 2. Requirements   Hardware  MX 8M Plus EVK Headphones with 3.5 mm audio jack Type-C power supply for i.MX 8M Plus EVK Micro USB to USB adapter cable Software  A recent prebuilt Linux BSP image from NXP.com ( we tested this on 5.15.35 and 5.15.5 releases) Windows 10 or Ubuntu 20.04 Workstation MCUXpresso SDK for i.MX 8M Plus ( available from:  Welcome | MCUXpresso SDK Builder (nxp.com)) 3. Reference documentation for this example   MCUXpresso SDK   [1] Getting Started with MCUXpresso SDK for EVK-MIMX8MP     Available within the MCUXpresso SDK package:  \{INSTALL PATH}\SDK_X_X_X_EVK-MIMX8MP\docs    [2] SAI low power audio README file Contains instructions for the SAI Low Power Audio Demo.  Available within the MCUXpresso SDK package: \{INSTALL PATH}\SDK_X_X_X_EVK-MIMX8MP\boards\evkmimx8mp\demo_apps\sai_low_power_audio   4. Downloading a pre-built Linux BSP image for the i.MX 8M Plus   I will make use of the prebuilt Linux Image for the i.MX 8M Plus EVK for demonstrating the demo works.  At the moment of writing this time, I used the 5.15.32 release, although there are older releases like 5.10.5 that I tested and proved to work with no issues. This SAI Low Power Audio Demo shall work for other processors on the i.MX 8M family. Although specific instructions ( e.g. load address for M-core binary load) might require some adaptation. For M-core load address, please refer to the specific MCUXpresso SDK documentation for each processor. The prebuilt Linux image (5.15.32) for the i.MX 8M Plus EVK can be downloaded from here: https://www.nxp.com/webapp/Download?colCode=L5.15.32_2.0.0_MX8MP&appType=license You can download other releases from here: Embedded Linux for i.MX Applications Processors | NXP Semiconductors . Select a version and a board and select download. 5. Flashing the BSP image   If you are using an Ubuntu 20.04 workstation, I recommend you to flash the image using dd. For this, you can refer to the i.MX Linux User's Guide: Section - 4.3.2 Copying the full SD card image - https://www.nxp.com/docs/en/user-guide/IMX_LINUX_USERS_GUIDE.pdf sudo dd if=.wic of=/dev/sdx bs=1M && sync NOTE: when using dd, ALWAYS, double check the of device that you are about to writing. Messing up with another location or partition will harm your system   If you are following this document on a Windows machine: You can use the Universal Update Utility (UUU) to flash your image on either the board's eMMC or SD card. Document named UUU.pdf shall serve as your reference guide for further instructions and flashing examples. It is available along with UUU binary here: https://github.com/NXPmicro/mfgtools/releases Two examples are shown below for your convenience:                                     SD card flash                                                 uuu -b sd_all bootloader rootfs.sdcard.bz2                                     eMMC flash                                                 uuu -b emmc_all bootloader rootfs.sdcard.bz2        uuu uuu.auto NOTE: UUU is also compatible with Ubuntu NOTE: there are other engineers who like to use BalenaEtcher for flashing their BSP images. I have tested it and works on both Ubuntu and Windows 10 machines.   6. Preparing the BSP and booting up M7 core  using U-Boot   I am writing this upon the instructions contained on the README file for the low power audio example  [2]. Instructions ready to copy and paste will follow:   Instruct U-Boot to pass to the kernel the rpmsg device tree to enable communication between the A53 cluster and the M7 one: u-boot=>setenv fdtfile imx8mp-evk-rpmsg.dtb u-boot=>saveenv Load the M7 example: u-boot=>setenv mmcargs 'setenv bootargs ${jh_clk} console=${console} root=${mmcroot} snd_pcm.max_alloc_per_card=134217728' u-boot=>saveenv Now, we need to load the M4 with the demo. Refer to [1] for further information. If running the BSP on an SD card, make sure the example binary is listed on the boot partition as follows: fatls mmc 1:1 You shall see something similar to this:             imx8mp_m7_TCM_sai_low_power_audio.bin Open the serial terminal emulator for the M7. Out of the fourth ports listed when we plug the i.MX 8M Plus serial debug cable to the PC, the M7 is typically the last one listed.   All the serial ports available to the workstation when the i.MX 8M Plus serial cable is connected to it. NOTE: you may require to install addtitional COM drivers if you are running on Windows. I like doing the previous step so I can see the result of the next commands issued in U-boot to load the M7 image. fatload mmc 1:1 0x48000000 imx8mp_m7_TCM_sai_low_power_audio.bin; cp.b 0x48000000 0x7e0000 20000; bootaux 0x7e0000 Here is an screenshot that shows how the U-Boot's response should look: U-Boot response when loading the SAI low power audio example to the Cortex M7 That should have prompted the following message on the M7 terminal: M7-core is up!   Now, let’s move to user space! u-boot=> boot 7. Testing the example using a simple GStreamer pipeline   As soon as the O.S. finishes booting. We can see that M7 terminal prompts the following: M7 is now in STOP mode; waiting for some audio to beat the room! Confirm that the WM8960 is listed as audio card as follows: cat /proc/asound/cards             Listing avaialable audio cards. WM8960 should be present. Make note of the list. The wm8960 is listed a the third sound card. This is where I like to differ a bit from [2] and I suggest a quicker test in case of not having an audio file ready. We just simply use GStreamer to play an audiotest source. Please make sure to plug in your headphones onto the board’s 3.5 mm jack before.   The following GStreamer pipeline is using the WM8960 as an audiosink.  gst-launch-1.0 audiotestsrc ! alsasink device=hw:3   NOTE: please be cautious and not put the headphones directly in your head at the first attempt. The sound can be too loud to some people. This is what you should see on the M7 side: Stop the GStreamer pipeline issuing CTRL + C. M7 shall warn you about that: NOTE: you can use the aplay command to play audio as shown on [2]. However, I consider using a testsrc is much quicker and flexible for a quick test.  8. Additional information   Feel free to go ahead and tweak the GStreamer pipeline to change audio test source properties. audiotest src. This command will let you know the available options:            gst-inspect-1.0 audiotestsrc                         NOTE: you can navigate through the displayed list using the “d”key. Press “q’’ to quit. For example:     For example, I am reproducing sound using a different setup based on the list above: gst-launch-1.0 audiotestsrc freq=4000 volume=0.8 wave=8 ! alsasink device=hw:3 9.  Errata and future updates   TBD:     Add an example on how to define the default audio card and play the audio either using gst-play or building the pipeline using filesrc Comment on the limitations of the M7 core regarding sample rate and audio formats  
View full article
Case Description There is requirement need to control(enable/disable) regulator from user space. Regulator userspace-consumer driver can help. But it doesn’t support device tree. A patch for handling device tree is needed. linux/drivers/regulator/userspace-consumer.c    
View full article
The IOMUX module on i.MX 8M enables flexible I/O multiplexing, allowing users to configure each IO pad as one of selectable functions. The CSU (Central Security Unit) module on i.MX 8M can be used to configure some devices as secure only accessible to protect the security of these devices. But as the IOMUX is Non-Secure accessilbe and thus the pad function can be configured dynamicaly, there is one risk if hackers reconfigure the IO pad to make the device connected to other controller which is accessible to Non-Secure world. One solution for this issue is configuring the CSU to limit Non-Secure access to IOMUX, all IOMUX registers write operations are routed to Trusty OS. In the Trusty OS, add all sensitive IO resources to one blacklist, the IOMUX driver in Trusty OS should check and deny any write attemption to sensitive registers from Non-Secure world. One example patch set is attached to show how to assign the IOMUX to secure world and how to route the IOMUX write operations to Trusty OS. In this example, the USB Host pinctrl PAD on i.MX8MP EVK was assigned to secure world. The layout of the example codes are:     . ├── atf │ └── 0001-config-iomux-to-secure-write.patch --> ${MY_ANDROID}/vendor/nxp-opensource/arm-trusted-firmware ├── kernel │ └── 0001-Use-Trusty-OS-to-handle-iomux-registers-written-oper.patch --> ${MY_ANDROID}/vendor/nxp-opensource/kernel_imx/ ├── trusty │ └── 0001-Add-iomux-pinctrl-TEE-handler.patch --> ${MY_TRUSTY}/trusty/hardware/nxp └── u-boot └── 0001-Use-Trusty-OS-to-handle-IOMUX-operation.patch --> ${MY_ANDROID}/vendor/nxp-opensource/uboot-imx      
View full article
Sometimes we got CMA allocation error while there're still many free pages in CMA area.  This article analyze several cases/reason for this kind of failure.
View full article
On behalf of Gopise Yuan. In case some customer may make mistake in mechanical design, they may need to flip/mirror the screen. DPR in DPU can do this in a simple way. This patch demonstrate how to enable VFLIP and HFLIP in DPR to do a V+H flip (=180 rotate) of the screen
View full article
When working with an evaluation kit you will be provided with a System Controller Firmware (SCFW) binary included in your BSP. This scfw binary has been tailored for that specific board and you might need to modify some board dependencies to fit your specific hardware. This document aims to provide an overview on the SCFW porting process, for detailed information please refer to the System Controller Porting guide (sc_fw_port.pdf).   Setting up the system The SCFW is built on a Linux host. The steps to set-up your system are the following: Download the GNU ARM Embedded Toolchain: 6-2017-q2-update June 28, 2017 from the ARM website: Select a directory to untar the file unto, for instance: mkdir ~/gcc_toolchain cp ~/Downloads/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 ~/gcc_toolchain/ cd ~/gcc_toolchain/ tar xvjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   Set TOOLS environment variable to the directory containing the tool chain, "~/gcc_toolchain" on the example above, .bash_profile can also be modified to export this environment variable: export TOOLS=~/gcc_toolchain/ srec_cat is also necessary for the build, this is usually contained in the srecord package, on ubuntu you can do: sudo apt-get update sudo apt-get install srecord Now you can change to the porting kit directory (e.g. scfw_export_mx8qm) and build the scfw. System Controller Firmware Porting kit  The SCFW porting kit contains source files and object files that will allow you to modify the SCFW to work with your board. You can get the latest System Controller Firmware Porting kit from the i.MX Software and development webpage: Once you obtain the porting kit untar it: tar xvzf imx-scfw-porting-kit-1.1.tar.gz‍ You will see the following file structure: The porting kit is contained under packages, the README contains the instructions to extract the porting kit, basically: cd packages/ chmod a+x imx-scfw-porting-kit-1.1.bin ./imx-scfw-porting-kit-1.1.bin‍‍‍ You will be prompted to accept an End User License Agreement: Once you accept the agreement the porting kit will be extracted in a new folder, the folder structure is as follows: All documentation regarding SCFW is under doc/pdf or in html format if preferred, it is recommended to go over sc_fw_port.pdf. The porting kits for different SoC variants (QM A0, QM B0 and QXP B0) are under src packaged as tar.gz, all other files are SCFW libraries for different software packages, such as Linux, QNX, FreeRTOS, U-boot, ARM Trusted Firmware, etc...   If you will be working with several SoC variants (working with both QXP and QM) it is recommended to extract all porting kits into a single directory, that way you will be able to build for any variant from this directory, the command to do this is: cd imx-scfw-porting-kit-1.1/ cd src/ find scfw_export_mx8*.gz -exec tar --strip-components 1 --one-top-level=scfw_export_mx8 -xzvf {} \;‍‍‍ A scfw_export_mx8 folder will be created, from here you will be able to build SCFW for any supported variant. Or you can just extract the package for the variant you are interested on and use that. cd scfw_export_mx8/‍ All the build folders contain the results of building the SCFW and platform is where the source of the SCFW is stored.   All the code that is specific to a board configuration is under "platform/board/mx8<derivative>_<board_name>" where derivative is the i.MX8 silicon family such as QXP or QM, and board name is the name of the board the SCFW package is for. The first step in porting the SCFW to your board is to create a folder for your i.MX8 derivative and board, you can take one of the available board examples and rename the folder, that will provide you a project to get started with, for instance: cp -r platform/board/mx8qm_val/ platform/board/mx8qm_myBoard/‍‍‍‍‍‍‍‍‍‍ The board in this example will be called "myBoard" and it is for an i.MX8QM B0 device. To build a SCFW for this board simply call: make qm R=B0 B=myBoard‍‍‍‍‍‍‍‍‍‍‍‍ If the target is an i.MX8QXP simply take a board based on this device and change the call to "make qx". Additional information such as build options and in detailed boot information can be found in the SCFW porting guide (sc_fw_port.pdf), chapter 2 of this document is a great introduction to the porting process.   Overview and useful information Configuring the PMIC overview and board.c common modifications The main file that needs to be altered (if not the only) is the "board.c" file, it is located at "platform/board/mx8X_board/". The board.c file contains most of the board related information such as SCU UART ports, PMIC initialization routines, PMIC temperature alarms settings and you can also modify it to configure LDOs voltages and communicate with the PMIC in general. All functions in the board.c file are executed by the SCU itself and this gives you access to the I2C interface that is used to communicate with the PMIC. SoC resources that are powered by an external supply (PMIC LDO for instace) such as AP cores and GPUs are powered off/on by board_set_power_mode, the mapping of the resource to an specific PMIC supply happens in board_get_pmic_info, for instance in our i.MX8QM validation board using the A53 subsystem is powered by SW2 of the third PMIC (PMIC_2_ADDR addresses start at PMIC_0) on the PF100 PMIC card and by SW5 of the first PMIC (PMIC_0_ADDR) on the PF8100 PMIC card. case SC_SUBSYS_A53: pmic_init(); if (pmic_card == PF100) { pmic_id[0] = PMIC_2_ADDR; pmic_reg[0] = SW2; *num_regs = 1; } else {/* PF8100_dual Card */ pmic_id[0] = PMIC_0_ADDR; pmic_reg[0] = PF8100_SW5; *num_regs = 1; } break; ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ The voltages of SoC resources that are powered by an external supply (AP cores, GPUs, etc...) are managed by board_set_voltage in the board.c file. The mapping of resource to power supply occurs in board_get_pmic_info as in the example above. Eight "board resources" (SC_R_BOARD_R0, ... SC_R_BOARD_R7) are available, these resources allow you to define components in your board that the SCU can manage, for instance a sensor on your board powered by one of the PMIC LDOs can be mapped to a board resource and the board.c file can be modified to power on/off the sensor as well as modifying its voltage. Modifying the voltage on a board resource can be either be done by modifying the voltage at board_trans_resource_power (see below) or if the voltage needs to change at run time the function board_set_control can be modified to change the voltage whenever a miscellaneous call (more details in the Miscellaneous Service 101) is made on that resource. For instance to change the voltage on SC_R_BOARD_R7 you would have the following case to board_set_control: case SC_R_BOARD_R7: if (ctrl == SC_C_VOLTAGE) { /* Example only PMIC_X_ADDR and PMIC_SUPPLY need to match an actual device */ pmic_interface.pmic_set_voltage(PMIC_X_ADDR, PMIC_SUPPLY, val, step); } else return SC_ERR_PARM; break;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ The case above will be executed by the SCU every time the application calls the function below: sc_misc_set_control( ipc, SC_R_BOARD_R7, SC_C_VOLTAGE, voltage_val);‍‍‍‍‍‍‍‍ Powering on/off a board resource happens at board_trans_resource_power in the board.c file. For instance in NXP's validation board the PTN5150 on the board is managed through a board resource 0, and the power on/off is managed as follows: case BRD_R_BOARD_R0 : /* PTN5150 (use SC_R_BOARD_R0) */ if (pmic_ver.device_id == PF100_DEV_ID) { if (to_mode > SC_PM_PW_MODE_OFF) { pmic_interface.pmic_set_voltage(PMIC_2_ADDR, VGEN6, 3300, SW_RUN_MODE); pmic_interface.pmic_set_mode(PMIC_2_ADDR, VGEN6, VGEN_MODE_ON); } else { pmic_interface.pmic_set_mode(PMIC_2_ADDR, VGEN6, VGEN_MODE_OFF); } } else {/* PF8100_dual Card */ if (to_mode > SC_PM_PW_MODE_OFF) { pmic_interface.pmic_set_voltage(PMIC_1_ADDR, PF8100_LDO1, 3300, REG_RUN_MODE); pmic_interface.pmic_set_mode(PMIC_1_ADDR, PF8100_LDO1, RUN_EN_STBY_EN); } else { pmic_interface.pmic_set_mode(PMIC_1_ADDR, PF8100_LDO1, RUN_OFF_STBY_OFF); } } break;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ Whenever the function below is called from the application side the SCU will execute the code above: sc_pm_set_resource_power_mode(ipc, SC_R_BOARD_R0, SC_PM_PW_MODE_ON/OFF);‍‍‍‍‍‍‍‍ board_config_sc is used to mark resources that the SCU needs, such as the I2C module and pads used to communicate with the PMIC, any resource needed by the board.c functions to work should be marked in this function as not movable, for instance to keep the SCU I2C module the following line is added: rm_set_resource_movable(pt_sc, SC_R_SC_I2C, SC_R_SC_I2C, false);‍‍‍‍‍‍‍‍‍ The following pads are part of the SCU and the application will not be able to access them: - SC_P_SCU_PMIC_MEMC_ON - SC_P_SCU_WDOG_OUT - SC_P_PMIC_EARLY_WARNING - SC_P_PMIC_INT_B - SC_P_SCU_BOOT_MODE0 through SC_P_SCU_BOOT_MODE5 board_system_config is where early resource management occurs, this function is only called when the alt_config flag is set in the image, and it can create partitions and allocate resources to it. More details are found in the resource management service 101. board_get_pcie_clk_src defines the clock that the PCIe uses, it can be either BOARD_PCIE_PLL_EXTERNAL or BOARD_PCIE_PLL_INTERNAL. board_print is very useful to debug your changes the syntax is as follows: board_print(3, "Debug printout %d\n", val);‍‍‍‍‍‍‍ Where the first parameter is the Debug Level and from there on it works as a standard printf. The output will only be visible on the SCU debug output whenever the SCU is built with the corresponding debug level, in the case above the SCFW needs to be built as follows in order to see the output: make qm B=myBoard‍‍‍‍ DL=3 or higher (debug level goes from 0 to 5)‍‍‍‍‍‍‍   Usage examples The following utility shows how to make System Controller Firmware requests and provides a way to make such requests through command line interface on both QNX and Linux System Controller Firmware Command Line Utility for Linux and QNX   System Controller Firmware 101  
View full article
Here is a summary including kdump + crash porting in i.mx, the tool is very useful in crash issue. Overview What is Kdump + Crash Preconditions kernel kexec Step actions Crash tool Analysis of use cases   Besides that, I summary the dumper tools including kdump and pstore, the respective patches shown as below: Kdump: Customer can apply below patch in config and cmdline, which has been confirmed on linux os. As memory is very precious to android, so kdump is not worth adopting. Config:        First kernel:       CONFIG_KEXEC=y       CONFIG_SYSFS=y       CONFIG_DEBUG_INFO=Y        Capture kernel:       CONFIG_CRASH_DUMP=y       CONFIG_PROC_VMCORE=y Cmdline:        crashkernel=512M Pstore: Customer can apply below patch in config and dts showing as below, which has been confirmed on linux and android os. Config: CONFIG_PSTORE_PMSG=y Dts: +               ramoops@0x91f00000 { +                       compatible = "ramoops"; +                       reg = <0 0x91f00000 0 0x00100000>; +                       record-size     = <0x00020000>; +                       console-size    = <0x00020000>; +                       ftrace-size     = <0x00020000>; +                       pmsg-size       = <0x00020000>; +               }; +                 decoder_boot: decoder-boot@84000000 {                         reg = <0 0x84000000 0 0x2000000>;                         no-map;   Reproduce steps Reboot the system by enter below command:       $ reboot Check the related log by enter below command:       $ ls /sys/fs/pstore/          console-ramoops-0 pmsg-ramoops-0
View full article
BSP: L5.15.5_1.0.0 Platform: i.MX8MPlus EVK Background   The function lpddr4_mr_read in BSP always return zero and this casue the customer can't use it to read MR registers in DRAM. This is a simple demo for reading MR registers. Patch Code   diff --git a/arch/arm/include/asm/arch-imx8m/ddr.h b/arch/arm/include/asm/arch-imx8m/ddr.h index 0f1e832c03..fd68996a23 100644 --- a/arch/arm/include/asm/arch-imx8m/ddr.h +++ b/arch/arm/include/asm/arch-imx8m/ddr.h @@ -721,6 +721,8 @@ int wait_ddrphy_training_complete(void); void ddrphy_init_set_dfi_clk(unsigned int drate); void ddrphy_init_read_msg_block(enum fw_type type); +unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr); + void update_umctl2_rank_space_setting(unsigned int pstat_num); void get_trained_CDD(unsigned int fsp); diff --git a/board/freescale/imx8mp_evk/spl.c b/board/freescale/imx8mp_evk/spl.c index 33bbbc09ac..85e40ffbbe 100644 --- a/board/freescale/imx8mp_evk/spl.c +++ b/board/freescale/imx8mp_evk/spl.c @@ -150,6 +150,40 @@ int board_fit_config_name_match(const char *name) return 0; } #endif +void lpddr4_get_info() +{ + int i = 0, attempts = 5; + + unsigned int ddr_info = 0; + unsigned int regs[] = { 5, 6, 7, 8 }; + + for(i = 0; i < ARRAY_SIZE(regs); i++){ + unsigned int data = 0; + data = lpddr4_mr_read(0xF,regs[i]); + ddr_info <<= 8; + ddr_info += (data & 0xFF); + switch (i) + { + case 0: + printf("DRAM INFO : Manufacturer ID = 0x%x",ddr_info); + if(ddr_info & 0Xff) + printf(", Micron\n"); + break; + case 1: + printf("DRAM INFO : Revision ID1 = 0x%x\n",ddr_info); + break; + case 2: + printf("DRAM INFO : Revision ID2 = 0x%x\n",ddr_info); + break; + case 3: + printf("DRAM INFO : I/O Width and Density = 0x%x\n",ddr_info); + break; + default: + break; + } + } + +} void board_init_f(ulong dummy) { @@ -187,6 +221,8 @@ void board_init_f(ulong dummy) /* DDR initialization */ spl_dram_init(); + + lpddr4_get_info(); board_init_r(NULL, 0); } diff --git a/drivers/ddr/imx/imx8m/ddrphy_utils.c b/drivers/ddr/imx/imx8m/ddrphy_utils.c index 326b92d784..f45eeaf552 100644 --- a/drivers/ddr/imx/imx8m/ddrphy_utils.c +++ b/drivers/ddr/imx/imx8m/ddrphy_utils.c @@ -194,8 +194,15 @@ unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr) tmp = reg32_read(DRC_PERF_MON_MRR0_DAT(0)); } while ((tmp & 0x8) == 0); tmp = reg32_read(DRC_PERF_MON_MRR1_DAT(0)); - tmp = tmp & 0xff; reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x4); + + while (tmp) { //try to find a significant byte in the word + if (tmp & 0xff) { + tmp &= 0xff; + break; + } + tmp >>= 8; + } return tmp; }     Test Result  
View full article
Many customer set GPIO as input or output functions. While they are confused on how to set GPIO property. This article describe on GPIO property setting tips, especially that input and out property setting are different. 
View full article
On behalf of Gopise Yuan. This is a debugging patch for adding support for showing interrupt status (same as ‘cat /proc/interrupts’) in Sysrq. Can be triggered by “y”. Might be useful for debugging some hang/stuck issue. Note: Only for debugging purpose. Triggering it in normal case may throttle current cpu and cause IPC/RCU abnormal due to long printing to console.
View full article
This is simple known-how for how to implement "boot animation" with DRM under i.MX8/X + Linux:   Code to refer to: ========================================================================= 1. kmscube: Either open source one or the customized on for i.MX will be OK: https://cgit.freedesktop.org/mesa/kmscube/ https://source.codeaurora.org/external/imx/kmscube-imx/ 2. Android display HAL: KmsDisplay.cpp   Known-how: ========================================================================= 1. Only one application can grab the master role of the DRM device. If need to control DRM from two applicaiton simultanously, possible solution:     A, Use "controlD" node instead of "card" node in /dev/dri/. This requires L4.14 or before. This device node was removed by two commits in L4.14.x:           8a357d10043c75e980e7fcdb60d2b913491564af           6449b088dd51dd5aa6b38455888bbf538d21f2fc     Can be brought back by reverting these two commits in L4.14.98.     B, Use framebuffer emulator to emulate a FB device (/dev/fb0). (not recommended due to lack of vsync). 2. Some kernel functions will re-config the DRM device during boot. This will cause display abnormal after user application has configured the DRM device. Better to disable these kernel features:       CONFIG_DRM_FBDEV_EMULATION       CONFIG_FRAMEBUFFER_CONSOLE 3. Use atomic mode of KMS API instead of legacy mode for any dynamically screen drawing application, such as video, game and etc. Atomic mode will have much better performance compare to legacy mode. The kmscube has sample code for both mode. 4. Better to do commit checking before doing any real commit, especially when doing display during boot. Sometimes some internal component in DRM is not fully ready after card device is present.       DRM_MODE_ATOMIC_ALLOW_MODESET 5. If video playback will be used, some points to remind:     a, Sample code for direct video decoding (in unit-test): imx-test/test/mxc_v4l2_vpu_test/     b, VPU in i.MX8/X only support tiled NV12 output and it has pixel alignment requirement (128). Need to use CPU or G2D to do un-tile, CSC and cropping. Sample code: <android>/vendor/nxp/fsl_imx_omx/OpenMAXIL/src/component/v4l2_common/G2dProcess.cpp If using G2D under Linux, it will support un-tile directly (through OpenCL internally).
View full article
 This article instruct customer how to develop on i.MX8MP NPU and how to debug performance. 
View full article
This article is to show how to use CLK2 for PCIe ref clock for i.MX8MQ. Test Environment  i.MX8MQ + BSP L5.10.52 Background In order to cost down, some customers used CLK2 as PCIe reference clock as below while no external OSC installed, which is different with i.MX8MQ EVK design, so no clock output for PCIe.  Checked L4.14.98_2.3.0 and found it added internal PLL for PCIe clock support. Solution The attached patch based on 4.14.98 can’t be used directly on 5.10.52, the following is the main modification for PLLOUT of PCIe clock. PLLOUT Monitor Configuration Register contains bits to control the clock that will be generated on the CCM clock mapped to CLK2_P/N.        
View full article
In some cases, i.MX board connect to different module. It has very tiny changes, such as just one gpio different driver strength. We can build an entire new software to handle this requirement. Here we introduce another way, using u-boot to modify the device tree(dtb) at runtime.   Here is u-boot fdt command for  How to use gpio-hog demo https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/How-to-use-gpio-hog-demo/ta-p/1317709   run loadfdt fdt addr ${fdt_addr_r} fdt print /soc/bus/pinctrl/uart3grp fdt rm /soc/bus/pinctrl/uart3grp fdt print serial2 fdt set serial2 status disabled fdt print serial2 fdt print gpio4 fdt resize fdt mknode gpio4 gpio_hog_demo fdt set gpio4/gpio_hog_demo gpio-hog fdt set gpio4/gpio_hog_demo gpios <7 0> fdt set gpio4/gpio_hog_demo output-high fdt print gpio4 run mmcargs run loadimage booti ${loadaddr} - ${fdt_addr_r} root@imx8mmevk:~# cat /sys/kernel/debug/gpio gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio: gpio-5 ( |PCIe DIS ) out hi gpio-13 ( |ir-receiver ) in hi IRQ ACTIVE LOW gpio-15 ( |cd ) in hi IRQ ACTIVE LOW gpiochip1: GPIOs 32-63, parent: platform/30210000.gpio, 30210000.gpio: gpio-38 ( |? ) out hi gpio-42 ( |reset ) out lo ACTIVE LOW gpio-51 ( |regulator-usdhc2 ) out lo gpiochip2: GPIOs 64-95, parent: platform/30220000.gpio, 30220000.gpio: gpio-80 ( |status ) out hi gpiochip3: GPIOs 96-127, parent: platform/30230000.gpio, 30230000.gpio: gpio-117 ( |PCIe reset ) out hi gpiochip4: GPIOs 128-159, parent: platform/30240000.gpio, 30240000.gpio: gpio-135 ( |gpio_hog_demo ) out hi gpio-141 ( |spi1 CS0 ) out hi ACTIVE LOW gpio-149 ( |wlf,mute ) out hi ACTIVE LOW root@imx8mmevk:~# [ 33.758914] VSD_3V3: disabling dtc_utils-v1.6.1-win-x86_64.zip by msys2   
View full article
Customer can force PCIE to work at GEN1/GEN2 mode if PCB layout is not good. Pls refer to: linux/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt:40:- fsl,max-link-speed: Specify PCI gen for link capability. Must be '2' for i.MX8M: diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi index f4dcf7ac3c98..262db6f93cb2 100755 --- a/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi @@ -1314,7 +1314,7 @@                     <&clk IMX8MQ_CLK_PCIE1_AUX>,                     <&clk IMX8MQ_CLK_PCIE1_PHY>;              clock-names = "pcie", "pcie_bus", "pcie_phy"; -            fsl,max-link-speed = <2>; +            fsl,max-link-speed = <1>;              ctrl-id = <0>;              power-domains = <&pcie0_pd>;              status = "disabled"; @@ -1344,7 +1344,7 @@                     <&clk IMX8MQ_CLK_PCIE2_AUX>,                     <&clk IMX8MQ_CLK_PCIE2_PHY>;              clock-names = "pcie", "pcie_bus", "pcie_phy"; -            fsl,max-link-speed = <2>; +            fsl,max-link-speed = <1>;              ctrl-id = <1>;              power-domains = <&pcie1_pd>;              status = "disabled"; diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c index 54459b52f526..a63de7e7bae0 100644 --- a/drivers/pci/dwc/pci-imx6.c +++ b/drivers/pci/dwc/pci-imx6.c @@ -1548,6 +1548,7 @@ static int imx_pcie_establish_link(struct imx_pcie *imx_pcie)       u32 tmp;       int ret;   +    dw_pcie_dbi_ro_wr_en(pci);       /*        * Force Gen1 operation when starting the link.  In case the link is        * started in Gen2 mode, there is a possibility the devices on the   i.MX8/8x: fsl-imx8dx.dtsi pcieb: pcie@0x5f010000 {               /*               * pcieb phyx1 lane1 in default, adjust it refer to the               * exact hw design.               */ . . . . .               power-domains = <&pd_pcie>;               fsl,max-link-speed = <1>;         /* 3=gen3, 1=gen1 */               hsio-cfg = <PCIEAX2PCIEBX1>;               hsio = <&hsio>;               ctrl-id = <1>; /* pcieb */               cpu-base-addr = <0x80000000>;               status = "disabled";        };   pci-imx6.c @@ -1799,6 +1799,7 @@ static int imx_pcie_establish_link(struct imx6_pcie *imx6_pcie)      u32 tmp;      int ret;   +    dw_pcie_dbi_ro_wr_en(pci);      /*       * Force Gen1 operation when starting the link.  In case the link is       * started in Gen2 mode, there is a possibility the devices on the @@ -1870,11 +1871,13 @@ static int imx_pcie_establish_link(struct imx6_pcie *imx6_pcie)             dev_info(dev, "Link: Gen2 disabled\n");      }   +    dw_pcie_dbi_ro_wr_dis(pci);      tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCSR);      dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf);      return 0;    err_reset_phy: +    dw_pcie_dbi_ro_wr_dis(pci);      dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",             dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0),             dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1));
View full article
     The following steps allow you to toggle a pin on i.MX 8M Mini EVK, you can use the EVK as not gate, trigger a wake up signal, etc. With an script and modifying the device tree you can read an input and get as output the invert input.   On the Host.   Cloning the Linux kernel repository.   Clone the i.MX Linux Kernel repo to the home directory. cd ~ git clone -b lf-5.10.72-2.2.0 https://source.codeaurora.org/external/imx/linux-imx cd linux-imx/   Patching the device tree.   Open the imx8mm-evk.dtsi file: vim arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi For the purpose of this example, uart3 has to be "disabled" in order to avoid pins conflict, so change "okay" to "disabled": &uart3 {        pinctrl-names = "default";        pinctrl-0 = <&pinctrl_uart3>;        assigned-clocks = <&clk IMX8MM_CLK_UART3>;        assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;        fsl,uart-has-rtscts;        status = "disabled"; }; Add the following lines in the iomuxc node: &iomuxc {       pinctrl-names = "default";       pinctrl-0 = <&pinctrl_hog>; ​       pinctrl_hog: hoggrp {               fsl,pins = <                       MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9               0x19                       MX8MM_IOMUXC_ECSPI1_MISO_GPIO5_IO8              0x19               >;       };   Build the device tree.   Setup your toolchain, for example: source /opt/fsl-imx-wayland/5.10-hardknott/environment-setup-cortexa53-crypto-poky-linux Generate config file. make imx_v8_defconfig Compile the device tree. make freescale/imx8mm-evk.dtb Copy the .dtb file to the EVK, for example with scp: scp imx8mm-evk.dtb root@<EVK_IP>:/home/root Alternatively, you may copy the .dtb file directly to the FAT32 partition where the Kernel and Device Tree files are located.   On the EVK Board.   Switching the device tree.   To copy the updated device tree to the corresponding partition, first create a directory. mkdir Partition_1 Mount the partition one. mount /dev/mmcblk1p1 Partition_1/ Copy or move the device tree into partition one. cp imx8mm-evk.dtb Partition_1/ Reboot the board. reboot   Create an script.   Use vi: vi toggle.sh Add the following lines: #!/bin/bash ​ echo 136 > /sys/class/gpio/export echo in > /sys/class/gpio/gpio136/direction ​ echo 137 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio137/direction echo 0 > /sys/class/gpio/gpio137/value ​ while : do ​ if [[($(cat /sys/class/gpio/gpio136/value) == "0")]]; then         echo 1 > /sys/class/gpio/gpio137/value else         echo 0 > /sys/class/gpio/gpio137/value        fi ​ done Save the file: :wq Change file permissions: chmod +x toggle.sh   Toggling a pin.   In this example we are using the pin "UART3_CTS" like an input and "UART3_RTS" like an output. To toggle the pin, run the script: ./toggle.sh
View full article
Background Some customers connect their imx running Android to the cloud, so reboot-bootloader and the use of fastboot oem unlock is not acceptable. This way the system is disconnected and cannot be operated remotely using adb. This article therefore proposes to execute oem unlock before the bootloader is started when the system is first run, which can be unlocked directly.   Patch diff --git a/drivers/fastboot/fb_fsl/fb_fsl_boot.c b/drivers/fastboot/fb_fsl/fb_fsl_boot.c index 86b919775a..d60cd248ee 100644 --- a/drivers/fastboot/fb_fsl/fb_fsl_boot.c +++ b/drivers/fastboot/fb_fsl/fb_fsl_boot.c @@ -529,6 +529,42 @@ bool __weak is_power_key_pressed(void) { return false; } +static void wipe_all_userdata(void) +{ + char response[FASTBOOT_RESPONSE_LEN]; + + /* Erase all user data */ + printf("Start userdata wipe process....\n"); + /* Erase /data partition */ + fastboot_wipe_data_partition(); + +#if defined (CONFIG_ANDROID_SUPPORT) || defined (CONFIG_ANDROID_AUTO_SUPPORT) + /* Erase the misc partition. */ + process_erase_mmc(FASTBOOT_PARTITION_MISC, response); +#endif + +#ifndef CONFIG_ANDROID_AB_SUPPORT + /* Erase the cache partition for legacy imx6/7 */ + process_erase_mmc(FASTBOOT_PARTITION_CACHE, response); +#endif + +#if defined(AVB_RPMB) && !defined(CONFIG_IMX_TRUSTY_OS) + printf("Start stored_rollback_index wipe process....\n"); + rbkidx_erase(); + printf("Wipe stored_rollback_index completed.\n"); +#endif + process_erase_mmc(FASTBOOT_PARTITION_METADATA, response); + printf("Wipe userdata completed.\n"); +} +void do_unlock(void) +{ + int status; + wipe_all_userdata(); + status = fastboot_set_lock_stat(FASTBOOT_UNLOCK); + if (status < 0) + return FASTBOOT_LOCK_ERROR; + printf("Unlock device\n"); +} int do_boota(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { ulong addr = 0; @@ -563,6 +599,9 @@ int do_boota(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { fastboot_set_lock_stat(FASTBOOT_LOCK); lock_status = FASTBOOT_LOCK; } + if (lock_status == FASTBOOT_LOCK){ + do_unlock(); + } bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false); avb_metric = get_timer(0);      
View full article
     The following steps allow you to add a pad Wakeup on i.MX 8QuadMax MEK CPU Board. On the Host.   Cloning the Linux kernel repository.   Clone the i.MX Linux Kernel repo to the home directory. cd ~ git clone -b lf-5.10.72-2.2.0 https://source.codeaurora.org/external/imx/linux-imx cd linux-imx/ Patching the device tree.   Open the imx8qm-mek.dts file: vim arch/arm64/boot/dts/freescale/imx8qm-mek.dts Add the following lines: &lsio_gpio2{       pad-wakeup-num = <1>;       pad-wakeup = <81 4 1>; }; In the line pad-wakeup-num = <1>; , the number "1" corresponds to the number of pads that you want to add. The line pad-wakeup = <81 4 1>; has three parameters: The first parameter corresponds to the "pin_id", you can find it in include/dt-bindings/pinctrl/pads-imx8qm.h , in this example we are using "IMX8QM_MIPI_CSI1_I2C0_SDA". The second parameter corresponds to the "'type'", you can find it in the i.MX 8QuadMax Applications Processor Reference Manual, in the page 802:   For this example we are using "LOW". The third parameter corresponds to the "line", the number of bit in 32bit gpio group, you can find it in include/dt-bindings/pinctrl/pads-imx8qm.h In this example, "IMX8QM_MIPI_CSI1_I2C0_SDA" belongs to gpio group 2, line 1. Build the device tree.   Setup your toolchain, for example: source /opt/fsl-imx-wayland/5.10-hardknott/environment-setup-cortexa53-crypto-poky-linux Generate config file. make imx_v8_defconfig Compile the device tree. make freescale/imx8qm-mek.dtb Copy the .dtb file to the MEK CPU Board, for example with scp: scp imx8qm-mek.dtb root@<MEK_CPU_Board_IP>:/home/root Alternatively, you may copy the .dtb file directly to the FAT32 partition where the Kernel and Device Tree files are located. On the MEK CPU Board.   Switching the device tree.   To copy the updated device tree to the corresponding partition, first create a directory. mkdir Partition_1 Mount the partition one. mount /dev/mmcblk1p1 Partition_1/ Copy or move the device tree into partition one. cp imx8qm-mek.dtb Partition_1/ Reboot the board. reboot How to wake up the i.MX 8QuadMax MEK CPU Board.   In this example a wire was soldered on "R204":     Run the following command on the MEK CPU Board: echo mem > /sys/power/state And you will see something like: [   53.769266] PM: suspend entry (deep) [   53.902130] Filesystems sync: 0.129 seconds [   53.908068] Freezing user space processes ... (elapsed 0.002 seconds) done. [   53.917189] OOM killer disabled. [   53.920420] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. [   53.929626] printk: Suspending console(s) (use no_console_suspend to debug) Connect the wire that was soldered on "R204" to ground, the MEK CPU Board will wake up and you will see something like: [   54.687125] fec 5b040000.ethernet eth0: Link is Down [   54.689876] PM: suspend devices took 0.756 seconds [   54.709570] Disabling non-boot CPUs ... [   54.710562] CPU1: shutdown [   54.711582] psci: CPU1 killed (polled 0 ms) [   54.714360] CPU2: shutdown [   54.715376] psci: CPU2 killed (polled 0 ms) [   54.717365] CPU3: shutdown [   54.718382] psci: CPU3 killed (polled 0 ms) [   54.719887] CPU4: shutdown [   54.720884] psci: CPU4 killed (polled 4 ms) [   54.722213] CPU5: shutdown [   54.723229] psci: CPU5 killed (polled 0 ms) [   54.724731] Enabling non-boot CPUs ... [   54.725388] Detected VIPT I-cache on CPU1 [   54.725423] GICv3: CPU1: found redistributor 1 region 0:0x0000000051b20000 [   54.725486] CPU1: Booted secondary processor 0x0000000001 [0x410fd034] [   54.726455] CPU1 is up [   54.726930] Detected VIPT I-cache on CPU2 [   54.726947] GICv3: CPU2: found redistributor 2 region 0:0x0000000051b40000 [   54.726976] CPU2: Booted secondary processor 0x0000000002 [0x410fd034] [   54.727478] CPU2 is up [   54.727955] Detected VIPT I-cache on CPU3 [   54.727971] GICv3: CPU3: found redistributor 3 region 0:0x0000000051b60000 [   54.728001] CPU3: Booted secondary processor 0x0000000003 [0x410fd034] [   54.728497] CPU3 is up [   54.729806] Detected PIPT I-cache on CPU4 [   54.729825] GICv3: CPU4: found redistributor 100 region 0:0x0000000051b80000 [   54.729857] CPU4: Booted secondary processor 0x0000000100 [0x410fd082] [   54.730490] CPU4 is up [   54.730985] Detected PIPT I-cache on CPU5 [   54.730999] GICv3: CPU5: found redistributor 101 region 0:0x0000000051ba0000 [   54.731021] CPU5: Booted secondary processor 0x0000000101 [0x410fd082] [   54.731679] CPU5 is up [   54.756440] hdmi_rx_hd_core_clk: failed to set clock parent -16 [   54.765828] gpio-mxc 5d0a0000.gpio: wakeup by pad, line 1 [   54.844242] ahci-imx 5f020000.sata: external osc is used. [   54.913582] caam 31400000.crypto: registering rng-caam [   54.918358] PM: resume devices took 0.148 seconds [   55.096663] OOM killer enabled. [   55.099814] Restarting tasks ... done. [   55.111833] PM: suspend exit  
View full article
     The following steps allow you to build a bootable image in two different ways and also how to enable and use SCFW debug monitor. There are four files needed to generate a bootable image: ├── bl31.bin ├── u-boot.bin   ├── mx8qm-ahab-container.img     └── scfw_tcm.bin There are some ways to get the four files, one way is with Yocto and other way is with stand alone build. Get the four files needed to generate a bootable image with Yocto.   To get the four files needed with Yocto, you have to build an i.MX 8QuadMax image, maybe some steps are not necessary. 1.-Host packages. sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib \ build-essential chrpath socat cpio python python3 python3-pip python3-pexpect \ xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa \ libsdl1.2-dev pylint3 xterm rsync curl 2.-Setting up the Repo utility. mkdir ~/bin (this step may not be needed if the bin folder already exists) curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo export PATH=~/bin:$PATH 3.-Yocto Project Setup. git config --global user.name "Your Name" git config --global user.email "Your Email" git config --list mkdir imx-yocto-bsp cd imx-yocto-bsp repo init -u https://source.codeaurora.org/external/imx/imx-manifest -b imx-linux-hardknott -m imx-5.10.72-2.2.0.xml repo sync 4.-Build configurations. DISTRO=fsl-imx-xwayland MACHINE=imx8qmmek source imx-setup-release.sh -b imx8qmmek 5.-Building an image. bitbake imx-image-full The four files needed to generate a bootable image are in: ~/imx-yocto-bsp/imx8qmmek/tmp/deploy/images/imx8qmmek/imx-boot-tools Note: With Yocto you can not enable the SCFW debug monitor. For more information see the i.MX Yocto Project User's Guide. Get the four files needed to generate a bootable image with stand alone build.   To build all required binaries from source you can use standard aarch64 Linux toolchain, on Ubuntu 20.04 LTS: sudo apt-get install gcc-aarch64-linux-gnu Get the bl31.bin file - Arm Trust Firmware.   Download source from: git clone -b lf-5.10.72-2.2.0 https://source.codeaurora.org/external/imx/imx-atf Build: cd imx-atf make clean PLAT=imx8qm CROSS_COMPILE=aarch64-linux-gnu- make PLAT=imx8qm CROSS_COMPILE=aarch64-linux-gnu- bl31 The compiled bl31.bin location: build/imx8qm/release/bl31.bin Get the u-boot.bin file - u-boot.   Download source from: git clone -b lf-5.10.72-2.2.0 https://source.codeaurora.org/external/imx/uboot-imx Build: cd uboot-imx make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- imx8qm_mek_defconfig make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- The compiled u-boot.bin location: ./u-boot.bin Get the mx8qmb0-ahab-container.img file - iMX Seco. wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-seco-3.7.4.bin chmod +x imx-seco-3.7.4.bin ./imx-seco-3.7.4.bin --auto-accept The mx8qmb0-ahab-container.img file location: imx-seco-3.7.4/firmware/seco/mx8qmb0-ahab-container.img Get the scfw_tcm.bin file - SCFW.   Download and Install a GNU Toolchain.   Look at the packages/imx-scfw-porting-kit-1.7.4/doc/pdf/ , chapter Porting Guide, sub-chapter Tool Chain to check which GNU Toolchain version corresponds to the SCFW you are building. The imx-scfw-porting-kit-1.7.4 version uses the GNU Toolchain version gcc-arm-none-eabi-8-2018-q4-major . It is recommended to install toolchain in “opt” folder: cd /opt sudo wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 sudo tar xjf gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 Download and Install a Arm GCC toolchain. It is recommended to install toolchain in “opt” folder: sudo wget https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz sudo tar -Jxvf gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz After installing the toolchain, set up the environment variable relevant for building. export ARCH=arm CROSS_COMPILE=/opt/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- export TOOLS=/opt Build the scfw_tcm.bin file. cd ~ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-scfw-porting-kit-1.7.4.bin chmod +x imx-scfw-porting-kit-1.7.4.bin ./imx-scfw-porting-kit-1.7.4.bin --auto-accept cd imx-scfw-porting-kit-1.7.4/src Extract the desired scfw porting kit: tar -xvf scfw_export_mx8qm_b0.tar.gz cd scfw_export_mx8qm_b0/ Build without debug monitor: make clean make qm B=mek R=B0 Build with debug monitor: make clean make qm B=mek D=1 M=1 R=B0 DDR_CON=imx8qm_dcd_1.6GHz The scfw_tcm.bin file location: build_mx8qm_b0/scfw_tcm.bin   Generate the bootable image.   Once you have the four files needed to generate a bootable image, use imx-mkimage tool. Download source from: git clone -b lf-5.10.72-2.2.0 https://source.codeaurora.org/external/imx/imx-mkimage Copy the four binaries to iMX8QM folder. You have to rename some files. If you got the four binaries with Yocto. cp ~/imx-yocto-bsp/imx8qmmek/tmp/deploy/images/imx8qmmek/imx-boot-tools/bl31-imx8qm.bin ~/imx-mkimage/iMX8QM/bl31.bin cp ~/imx-yocto-bsp/imx8qmmek/tmp/deploy/images/imx8qmmek/imx-boot-tools/u-boot-imx8qmmek.bin-sd ~/imx-mkimage/iMX8QM/u-boot.bin cp ~/imx-yocto-bsp/imx8qmmek/tmp/deploy/images/imx8qmmek/imx-boot-tools/mx8qmb0-ahab-container.img ~/imx-mkimage/iMX8QM cp ~/imx-yocto-bsp/imx8qmmek/tmp/deploy/images/imx8qmmek/imx-boot-tools/mx8qm-mek-scfw-tcm.bin ~/imx-mkimage/iMX8QM/scfw_tcm.bin If you got the four binaries with stand alone build. cp ~/imx-atf/build/imx8qm/release/bl31.bin ~/imx-mkimage/iMX8QM cp ~/uboot-imx/u-boot.bin ~/imx-mkimage/iMX8QM cp ~/imx-seco-3.7.4/firmware/seco/mx8qmb0-ahab-container.img ~/imx-mkimage/iMX8QM cp ~/imx-scfw-porting-kit-1.7.4/src/scfw_export_mx8qm_b0/build_mx8qm_b0/scfw_tcm.bin ~/imx-mkimage/iMX8QM Build the bootable image. cd ~/imx-mkimage make SOC=iMX8QM flash The compiled file is flash.bin and its location is: iMX8QM/flash.bin   Flash the bootable image.   To flash the bootable image follow the next steps: -Copy the flash.bin and uuu.exe in a folder. -Change SW2 on the base board to 000100 (from MSB to LSB, 1-ON and 0-OFF) to boot from the Serial Downloader. -Run the following command in Command Prompt: uuu.exe -b sd flash.bin -Power on the MEK CPU board.   SCFW debug monitor.        If the SCFW is compiled using the M=1 option (default is M=0) then it will include a debug monitor. This can be used to R/W memory or registers, R/W power state, and dump some resource manager state. Production SCFW should never have the monitor enabled (M=0, the default)!      The debug monitor allows command-line interaction via the SCU UART. Inclusion of the debug monitor affects SCFW timing and therefore should never be deployed in a product! Note the terminal needs to be in a mode that sends CR or LF for a new line (not CR+LF). The following commands are supported: Command                                   Description exit                                              exit the debug monitor quit                                              exit the debug monitor reset [mode]                                request reset with mode (default = board) reboot partition [type]                  request partition reboot with type (default = cold) md.b address [count]                  display count bytes at address md.w address [count]                 display count words at address md[.l] address [count]                 display count long-words at address mm.b address value                   modify byte at address mm.w address value                  modify word at address mm[.l] address value                  modify long-word at address ai.r ss sel addr                            read analog interface (AI) register ai.w ss sel addr data                  write analog interface (AI) register fuse.r word                                 read OTP fuse word fuse.w word value                      write value to OTP fuse word dump rm                                    dump all the resource manager (RM) info dump rm part [part]                    dump all partition info for part (default = all) dump rm rsrc [part]                    dump all resource info for part (default = all) dump rm mem [part]                  dump all memory info for part (default = all) dump rm pad [part]                    dump all pad info for part (default = all) power.r [resource]                     read/get power mode of resource (default = all) power.w resource mode            write/set power mode of resource to mode (off, stby, lp, on) info                                             display SCFW/SoC info like unique ID, etc. seco lifecycle change                send SECO lifecycle update command (change) to SECO seco info                                    display SECO info like Lifecycle, SNVS state, etc. seco debug                                dump SECO debug log seco events                               dump SECO event log seco commit                              commit SRK and/or SECO FW version update pmic.r id reg                               read pmic register pmic.w id reg val                        write pmic register pmic.l id                                      list pmic info (rail voltages, etc) Resource and subsystem (ss) arguments are specified by name. All numeric arguments are decimal unless prefixed with 0x (for hex) or 0 (for octal). Testing SCFW debug monitor to display count long-words at address on Linux side and on SCU side. -Change SW2 on the base board to 001100 (from MSB to LSB, 1-ON and 0-OFF) to boot from the SD card. -Power on the MEK CPU board. -Open Tera Term and you will see: Hello from SCU (Build 5263, Commit 9b3d006e, Aug 20 2021 12:20:10) ​ DDR frequency = 1596000000  ROM boot time = 262368 usec      Boot time = 24583 usec         Banner = 10 usec           Init = 9038 usec         Config = 3232 usec            DDR = 2677 usec        SConfig = 444 usec           Prep = 5039 usec ​ *** Debug Monitor *** ​ >$ -Run the following commands: power.r power.w db on power.w dblogic on power.w mu_1a on -Example reading on Linux side: md.l 0x5d1c0000 10 -You will see: >$ md.l 0x5d1c0000 10 5d1c0000: 00000000 00000000 00000000 00000000 5d1c0010: 00010201 23c34600 d63fdb21 00000000 5d1c0020: 00f00200 18000000 -Example reading on SCU side: md.l 0x41cac080 10 -You will see: >$ md.l 0x41cac080 10 41cac080: 00000000 00000000 00000000 00000000 41cac090: 0d070201 ff0001f1 ffff8000 ffff00fb 41cac0a0: 00f00000 18000000 For more information see the System Controller Firmware Porting Guide.
View full article