Customer requirement: Use NOR boot as a backup — boot from NOR, then mount kernel, DTB, and rootfs from NAND.
Test module: https://www.nxp.com/design/design-center/development-boards-and-designs/m2-nand-flash-daughter-card:M2-NAND-FLASH
1. Why Does U-Boot Source Need Modification on i.MX95?
i.MX93's boot ROM initializes the SD3_XXX and SD1_XXX PADs. On the i.MX93 EVK design, SD3_XXX is routed to the M.2 connector, and SD1_XXX is connected to eMMC.
For i.MX95, the boot ROM only initializes the XSPI1_XXX PADs. The FlexSPI signals can be muxed out from SD3_XXX, but the boot ROM cannot boot from SD3_XXX.
Due to these differences, the uboot.bin flashed into NOR must have the ability to read NAND. However, the default BSP always reads from NOR, so U-Boot must be modified to activate the M.2 NAND module.
2. Flashing NAND
To flash NAND, a custom UUU script must be used. Using the built-in UUU spinand flashing script is not recommended — the built-in script assumes NAND is accessible in U-Boot, but the default imx-boot uses NOR.
2.1 UUU Script
uuu_version 1.2.39
# Please replace below item with actual name
# @_flash_fw.bin | boot loader firmware, for i.MX8QM/QX, it's different from _flash.bin, for all other platforms, it's same as _flash.bin
# @_flash.bin | boot loader file burn to NAND
# @_Image | linux kernel image, zImage for arm32, Image for arm64
# @_board.dtb | board dtb file
# @_initramfs.cpio.zst.uboot | initramfs
# @_tee | optee image
# @_rootfs.tar.zst | rootfs
# This command will be run when i.MX6/7 i.MX8MM, i.MX8MQ
SDP: boot -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi
# This command will be run when ROM support stream mode
# i.MX8QXP, i.MX8QM, skip QSPI header
SDPS: boot -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi -skipfhdr
# These commands will be run when use SPL and will be skipped if no spl
# SDPU will be deprecated. please use SDPV instead of SDPU
# {
SDPU: delay 1000
SDPU: write -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi -offset 0x10000 -skipfhdr
SDPU: jump
# }
# These commands will be run when use SPL and will be skipped if no spl
# if (SPL support SDPV)
# {
SDPV: delay 1000
SDPV: write -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi -skipspl -skipfhdr
SDPV: jump
# }
FB: ucmd setenv fastboot_buffer ${loadaddr}
FB: download -f Image.bin
FB: ucmd setenv fastboot_buffer ${fdt_addr}
FB: download -f imx95-19x19-evk.dtb
FB: ucmd setenv fastboot_buffer ${initrd_addr}
FB: download -f fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.zst.u-boot
FB: ucmd setenv bootargs ${bootargs} ${mtdparts}
FB: ucmd setenv fdtfile imx95-19x19-evk.dtb
#FB: ucmd setenv bootargs console=ttymxc3,115200 ${mtdparts}
FB: acmd ${kboot} ${loadaddr} ${initrd_addr} ${fdt_addr}
FBK: ucmd cat /proc/mtd
FBK: ucmd rm -f /tmp/mtd.sh
FBK: ucmd cat /proc/mtd | while read dev size erase name; do mtd=`echo $dev | sed 's/mtd//;s/://'`; name=`echo $name | tr -d '"'`; echo export $name=$mtd >> /tmp/mtd.sh; done
# mapping name
FBK: ucmd . /tmp/mtd.sh; [ -n "${bootloader}" ] && echo export nandboot=${bootloader} >> /tmp/mtd.sh
FBK: ucmd . /tmp/mtd.sh; [ -n "${kernel}" ] && echo export nandkernel=${kernel} >> /tmp/mtd.sh
FBK: ucmd . /tmp/mtd.sh; [ -n "${dtb}" ] && echo export nanddtb=${dtb} >> /tmp/mtd.sh
FBK: ucmd . /tmp/mtd.sh; [ -n "${rootfs}" ] && echo export nandrootfs=${rootfs} >> /tmp/mtd.sh
FBK: ucmd chmod 755 /tmp/mtd.sh
FBK: ucmd cat /tmp/mtd.sh
FBK: ucmd mount -t debugfs debugfs /sys/kernel/debug || true
# write boot loader — this partition was set to read-only in DTS during testing, skip erase for now
# FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nandboot} 0 0
# FBK: ucp imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi t:/tmp/boot
# FBK: ucmd . /tmp/mtd.sh; cd /tmp; soc=`cat /sys/devices/soc0/soc_id 2>/dev/null`; pad=""; case "$soc" in MX8Q*|MX8DXL*|MX8MN*|MX8MP*) ;; *) pad="-x" ;; esac; kobs-ng init $pad -v --chip_0_device_path=/dev/mtd${nandboot} /tmp/boot
# burn kernel
FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nandkernel} 0 0
FBK: acmd . /tmp/mtd.sh; nandwrite -p /dev/mtd${nandkernel} -
FBK: ucp Image.bin t:-
FBK: sync
# burn dtb
FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nanddtb} 0 0
FBK: ucp imx95-19x19-evk.dtb t:/tmp/dtb
FBK: ucmd . /tmp/mtd.sh; nandwrite -p /dev/mtd${nanddtb} /tmp/dtb
# burn uTee
# FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nandtee} 0 0
# FBK: ucp _tee t:/tmp/tee
# FBK: ucmd . /tmp/mtd.sh; nandwrite -p /dev/mtd${nandtee} /tmp/tee
# burn rootfs
FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nandrootfs} 0 0
FBK: ucmd ubidetach /dev/ubi_ctrl -m ${nandrootfs} || true
FBK: ucmd . /tmp/mtd.sh; ubiattach /dev/ubi_ctrl -m ${nandrootfs}
FBK: ucmd ubimkvol /dev/ubi0 -N nandrootfs -m
FBK: ucmd mkdir -p /mnt/mtd
FBK: ucmd mount -t ubifs ubi0:nandrootfs /mnt/mtd
FBK: acmd export EXTRACT_UNSAFE_SYMLINKS=1; tar --zstd --warning=no-timestamp -x -C /mnt/mtd
FBK: ucp core-image-base-imx95-19x19-lpddr5-evk.rootfs-20260429064745.tar.zst t:-
FBK: sync
FBK: ucmd umount /mnt/mtd
FBK: done
2.2 Linux Patch
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index d21335d8af84..0db2cefbab01 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -388,17 +388,47 @@ &flexspi1 {
pinctrl-0 = <&pinctrl_flexspi1>;
status = "okay";
- mt35xu01gbba: flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_flexspi1_reset>;
- reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
+ W25N02KWZEIR: flash@0 {
+ compatible = "spi-nand";
#address-cells = <1>;
#size-cells = <1>;
- spi-max-frequency = <200000000>;
- spi-tx-bus-width = <8>;
- spi-rx-bus-width = <8>;
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0x000000 0x800000>; // 8MB
+ // read-only;//if you hope imx-boot read only
+ };
+
+ partition@1 {
+ label = "config";
+ reg = <0x800000 0x800000>; //8MB
+ };
+
+ partition@2 {
+ label = "kernel";
+ reg = <0x1000000 0x2800000>; //40MB
+ };
+
+ partition@3 {
+ label = "dtb";
+ reg = <0x3800000 0x20000>; //128K
+ };
+
+ partition@4 {
+ label = "rootfs";
+ reg = <0x3820000 0xFFFFFFFF>;
+ linux,rootfs;
+ };
+ };
};
};
@@ -887,17 +917,12 @@ IMX95_PAD_GPIO_IO27__CAN2_RX 0x39e
pinctrl_flexspi1: flexspi1grp {
fsl,pins = <
- IMX95_PAD_XSPI1_SS0_B__FLEXSPI1_A_SS0_B 0x3fe
- IMX95_PAD_XSPI1_SCLK__FLEXSPI1_A_SCLK 0x3fe
- IMX95_PAD_XSPI1_DQS__FLEXSPI1_A_DQS 0x3fe
- IMX95_PAD_XSPI1_DATA0__FLEXSPI1_A_DATA_BIT0 0x3fe
- IMX95_PAD_XSPI1_DATA1__FLEXSPI1_A_DATA_BIT1 0x3fe
- IMX95_PAD_XSPI1_DATA2__FLEXSPI1_A_DATA_BIT2 0x3fe
- IMX95_PAD_XSPI1_DATA3__FLEXSPI1_A_DATA_BIT3 0x3fe
- IMX95_PAD_XSPI1_DATA4__FLEXSPI1_A_DATA_BIT4 0x3fe
- IMX95_PAD_XSPI1_DATA5__FLEXSPI1_A_DATA_BIT5 0x3fe
- IMX95_PAD_XSPI1_DATA6__FLEXSPI1_A_DATA_BIT6 0x3fe
- IMX95_PAD_XSPI1_DATA7__FLEXSPI1_A_DATA_BIT7 0x3fe
+ IMX95_PAD_SD3_CMD__FLEXSPI1_A_SS0_B 0x3fe
+ IMX95_PAD_SD3_CLK__FLEXSPI1_A_SCLK 0x3fe
+ IMX95_PAD_SD3_DATA0__FLEXSPI1_A_DATA_BIT0 0x3fe
+ IMX95_PAD_SD3_DATA1__FLEXSPI1_A_DATA_BIT1 0x3fe
+ IMX95_PAD_SD3_DATA2__FLEXSPI1_A_DATA_BIT2 0x3fe
+ IMX95_PAD_SD3_DATA3__FLEXSPI1_A_DATA_BIT3 0x3fe
>;
};
2.3 Flashing Log
2:31-182BA9E87D9840BA>Start Cmd:SDPS: boot -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi -skipfhdr
100%2:31-182BA9E87D9840BA>Okay (5.364s)
New USB Device Attached at 2:31-182BA9E87D9840BA
2:31-182BA9E87D9840BA>Start Cmd:SDPV: delay 1000
2:31-182BA9E87D9840BA>Okay (1.009s)
2:31-182BA9E87D9840BA>Start Cmd:SDPV: write -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi -skipspl -skipfhdr
100%2:31-182BA9E87D9840BA>Okay (3.165s)
2:31-182BA9E87D9840BA>Start Cmd:SDPV: jump
100%2:31-182BA9E87D9840BA>Okay (0.017s)
New USB Device Attached at 2:31-182BA9E87D9840BA
2:31-182BA9E87D9840BA>Start Cmd:FB: ucmd setenv fastboot_buffer ${loadaddr}
2:31-182BA9E87D9840BA>Okay (0.014s)
2:31-182BA9E87D9840BA>Start Cmd:FB: download -f Image.bin
2:31-182BA9E87D9840BA>Okay (1.715s)
2:31-182BA9E87D9840BA>Start Cmd:FB: ucmd setenv fastboot_buffer ${fdt_addr}
2:31-182BA9E87D9840BA>Okay (0.011s)
2:31-182BA9E87D9840BA>Start Cmd:FB: download -f imx95-19x19-evk.dtb
2:31-182BA9E87D9840BA>Okay (0.026s)
2:31-182BA9E87D9840BA>Start Cmd:FB: ucmd setenv fastboot_buffer ${initrd_addr}
2:31-182BA9E87D9840BA>Okay (0.011s)
2:31-182BA9E87D9840BA>Start Cmd:FB: download -f fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.zst.u-boot
2:31-182BA9E87D9840BA>Okay (0.702s)
2:31-182BA9E87D9840BA>Start Cmd:FB: ucmd setenv bootargs ${bootargs} ${mtdparts}
2:31-182BA9E87D9840BA>Okay (0.011s)
2:31-182BA9E87D9840BA>Start Cmd:FB: ucmd setenv fdtfile imx95-19x19-evk.dtb
2:31-182BA9E87D9840BA>Okay (0.011s)
2:31-182BA9E87D9840BA>Start Cmd:FB: acmd ${kboot} ${loadaddr} ${initrd_addr} ${fdt_addr}
2:31-182BA9E87D9840BA>Okay (0.007s)
New USB Device Attached at 2:31-0000000000000000
2:31-0000000000000000>Start Cmd:FBK: ucmd cat /proc/mtd
dev: size erasesize name
mtd0: 00800000 00020000 "bootloader"
mtd1: 00800000 00020000 "config"
mtd2: 02800000 00020000 "kernel"
mtd3: 00020000 00020000 "dtb"
mtd4: 0c7e0000 00020000 "rootfs"
2:31-0000000000000000>Okay (0.015s)
2:31-0000000000000000>Start Cmd:FBK: ucmd rm -f /tmp/mtd.sh
2:31-0000000000000000>Okay (0.007s)
2:31-0000000000000000>Start Cmd:FBK: ucmd cat /proc/mtd | while read dev size erase name; do mtd=`echo $dev | sed 's/mtd//;s/://'`; name=`echo $name | tr -d '"'`; echo export $name=$mtd >> /tmp/mtd.sh; done
2:31-0000000000000000>Okay (0.077s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; [ -n "${bootloader}" ] && echo export nandboot=${bootloader} >> /tmp/mtd.sh
2:31-0000000000000000>Okay (0.006s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; [ -n "${kernel}" ] && echo export nandkernel=${kernel} >> /tmp/mtd.sh
2:31-0000000000000000>Okay (0.008s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; [ -n "${dtb}" ] && echo export nanddtb=${dtb} >> /tmp/mtd.sh
2:31-0000000000000000>Okay (0.006s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; [ -n "${rootfs}" ] && echo export nandrootfs=${rootfs} >> /tmp/mtd.sh
2:31-0000000000000000>Okay (0.008s)
2:31-0000000000000000>Start Cmd:FBK: ucmd chmod 755 /tmp/mtd.sh
2:31-0000000000000000>Okay (0.007s)
2:31-0000000000000000>Start Cmd:FBK: ucmd cat /tmp/mtd.sh
export name=dev
export bootloader=0
export config=1
export kernel=2
export dtb=3
export rootfs=4
export nandboot=0
export nandkernel=2
export nanddtb=3
export nandrootfs=4
2:31-0000000000000000>Okay (0.007s)
2:31-0000000000000000>Start Cmd:FBK: ucmd mount -t debugfs debugfs /sys/kernel/debug || true
2:31-0000000000000000>Okay (0.01s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nandkernel} 0 0
Erasing 40960 Kibyte @ 0 -- 100 % complete
2:31-0000000000000000>Okay (0.856s)
2:31-0000000000000000>Start Cmd:FBK: acmd . /tmp/mtd.sh; nandwrite -p /dev/mtd${nandkernel} -
2:31-0000000000000000>Okay (0.051s)
2:31-0000000000000000>Start Cmd:FBK: ucp Image.bin t:-
33%Writing data to block 0 at offset 0x0
Writing data to block 1 at offset 0x20000
Writing data to block 2 at offset 0x40000
Writing data to block 3 at offset 0x60000
Writing data to block 4 at offset 0x80000
Writing data to block 5 at offset 0xa0000
Writing data to block 6 at offset 0xc0000
Writing data to block 7 at offset 0xe0000
Writing data to block 8 at offset 0x100000
Writing data to block 9 at offset 0x120000
Writing data to block 10 at offset 0x140000
Writing data to block 11 at offset 0x160000
Writing data to block 12 at offset 0x180000
Writing data to block 13 at offset 0x1a0000
Writing data to block 14 at offset 0x1c0000
Writing data to block 15 at offset 0x1e0000
Writing data to block 16 at offset 0x200000
Writing data to block 17 at offset 0x220000
Writing data to block 18 at offset 0x240000
Writing data to block 19 at offset 0x260000
Writing data to block 20 at offset 0x280000
Writing data to block 21 at offset 0x2a0000
Writing data to block 22 at offset 0x2c0000
Writing data to block 23 at offset 0x2e0000
Writing data to block 24 at offset 0x300000
Writing data to block 25 at offset 0x320000
Writing data to block 26 at offset 0x340000
Writing data to block 27 at offset 0x360000
Writing data to block 28 at offset 0x380000
Writing data to block 29 at offset 0x3a0000
Writing data to block 30 at offset 0x3c0000
Writing data to block 31 at offset 0x3e0000
Writing data to block 32 at offset 0x400000
Writing data to block 33 at offset 0x420000
Writing data to block 34 at offset 0x440000
Writing data to block 35 at offset 0x460000
Writing data to block 36 at offset 0x480000
Writing data to block 37 at offset 0x4a0000
Writing data to block 38 at offset 0x4c0000
Writing data to block 39 at offset 0x4e0000
Writing data to block 40 at offset 0x500000
Writing data to block 41 at offset 0x520000
Writing data to block 42 at offset 0x540000
Writing data to block 43 at offset 0x560000
Writing data to block 44 at offset 0x580000
Writing data to block 45 at offset 0x5a0000
Writing data to block 46 at offset 0x5c0000
Writing data to block 47 at offset 0x5e0000
Writing data to block 48 at offset 0x600000
Writing data to block 49 at offset 0x620000
Writing data to block 50 at offset 0x640000
Writing data to block 51 at offset 0x660000
Writing data to block 52 at offset 0x680000
Writing data to block 53 at offset 0x6a0000
Writing data to block 54 at offset 0x6c0000
Writing data to block 55 at offset 0x6e0000
Writing data to block 56 at offset 0x700000
Writing data to block 57 at offset 0x720000
Writing data to block 58 at offset 0x740000
Writing data to block 59 at offset 0x760000
Writing data to block 60 at offset 0x780000
Writing data to block 61 at offset 0x7a0000
Writing data to block 62 at offset 0x7c0000
Writing data to block 63 at offset 0x7e0000
Writing data to block 64 at offset 0x800000
Writing data to block 65 at offset 0x820000
Writing data to block 66 at offset 0x840000
Writing data to block 67 at offset 0x860000
Writing data to block 68 at offset 0x880000
Writing data to block 69 at offset 0x8a0000
Writing data to block 70 at offset 0x8c0000
Writing data to block 71 at offset 0x8e0000
Writing data to block 72 at offset 0x900000
Writing data to block 73 at offset 0x920000
Writing data to block 74 at offset 0x940000
Writing data to block 75 at offset 0x960000
Writing data to block 76 at offset 0x980000
Writing data to block 77 at offset 0x9a0000
Writing data to block 78 at offset 0x9c0000
Writing data to block 79 at offset 0x9e0000
Writing data to block 80 at offset 0xa00000
Writing data to block 81 at offset 0xa20000
Writing data to block 82 at offset 0xa40000
Writing data to block 83 at offset 0xa60000
Writing data to block 84 at offset 0xa80000
Writing data to block 85 at offset 0xaa0000
Writing data to block 86 at offset 0xac0000
Writing data to block 87 at offset 0xae0000
Writing data to block 88 at offset 0xb00000
Writing data to block 89 at offset 0xb20000
Writing data to block 90 at offset 0xb40000
Writing data to block 91 at offset 0xb60000
Writing data to block 92 at offset 0xb80000
65%t offset 0xba0000k 93 a
Writing data to block 94 at offset 0xbc0000
Writing data to block 95 at offset 0xbe0000
Writing data to block 96 at offset 0xc00000
Writing data to block 97 at offset 0xc20000
Writing data to block 98 at offset 0xc40000
Writing data to block 99 at offset 0xc60000
Writing data to block 100 at offset 0xc80000
Writing data to block 101 at offset 0xca0000
Writing data to block 102 at offset 0xcc0000
Writing data to block 103 at offset 0xce0000
Writing data to block 104 at offset 0xd00000
Writing data to block 105 at offset 0xd20000
Writing data to block 106 at offset 0xd40000
Writing data to block 107 at offset 0xd60000
Writing data to block 108 at offset 0xd80000
Writing data to block 109 at offset 0xda0000
Writing data to block 110 at offset 0xdc0000
Writing data to block 111 at offset 0xde0000
Writing data to block 112 at offset 0xe00000
Writing data to block 113 at offset 0xe20000
Writing data to block 114 at offset 0xe40000
Writing data to block 115 at offset 0xe60000
Writing data to block 116 at offset 0xe80000
Writing data to block 117 at offset 0xea0000
Writing data to block 118 at offset 0xec0000
Writing data to block 119 at offset 0xee0000
Writing data to block 120 at offset 0xf00000
Writing data to block 121 at offset 0xf20000
Writing data to block 122 at offset 0xf40000
Writing data to block 123 at offset 0xf60000
Writing data to block 124 at offset 0xf80000
Writing data to block 125 at offset 0xfa0000
Writing data to block 126 at offset 0xfc0000
Writing data to block 127 at offset 0xfe0000
Writing data to block 128 at offset 0x1000000
Writing data to block 129 at offset 0x1020000
Writing data to block 130 at offset 0x1040000
Writing data to block 131 at offset 0x1060000
Writing data to block 132 at offset 0x1080000
Writing data to block 133 at offset 0x10a0000
Writing data to block 134 at offset 0x10c0000
Writing data to block 135 at offset 0x10e0000
Writing data to block 136 at offset 0x1100000
Writing data to block 137 at offset 0x1120000
Writing data to block 138 at offset 0x1140000
Writing data to block 139 at offset 0x1160000
Writing data to block 140 at offset 0x1180000
Writing data to block 141 at offset 0x11a0000
Writing data to block 142 at offset 0x11c0000
Writing data to block 143 at offset 0x11e0000
Writing data to block 144 at offset 0x1200000
Writing data to block 145 at offset 0x1220000
Writing data to block 146 at offset 0x1240000
Writing data to block 147 at offset 0x1260000
Writing data to block 148 at offset 0x1280000
Writing data to block 149 at offset 0x12a0000
Writing data to block 150 at offset 0x12c0000
Writing data to block 151 at offset 0x12e0000
Writing data to block 152 at offset 0x1300000
Writing data to block 153 at offset 0x1320000
Writing data to block 154 at offset 0x1340000
Writing data to block 155 at offset 0x1360000
Writing data to block 156 at offset 0x1380000
Writing data to block 157 at offset 0x13a0000
Writing data to block 158 at offset 0x13c0000
Writing data to block 159 at offset 0x13e0000
Writing data to block 160 at offset 0x1400000
Writing data to block 161 at offset 0x1420000
Writing data to block 162 at offset 0x1440000
Writing data to block 163 at offset 0x1460000
Writing data to block 164 at offset 0x1480000
Writing data to block 165 at offset 0x14a0000
Writing data to block 166 at offset 0x14c0000
Writing data to block 167 at offset 0x14e0000
Writing data to block 168 at offset 0x1500000
Writing data to block 169 at offset 0x1520000
Writing data to block 170 at offset 0x1540000
Writing data to block 171 at offset 0x1560000
Writing data to block 172 at offset 0x1580000
Writing data to block 173 at offset 0x15a0000
Writing data to block 174 at offset 0x15c0000
Writing data to block 175 at offset 0x15e0000
Writing data to block 176 at offset 0x1600000
Writing data to block 177 at offset 0x1620000
Writing data to block 178 at offset 0x1640000
Writing data to block 179 at offset 0x1660000
Writing data to block 180 at offset 0x1680000
Writing data to block 181 at offset 0x16a0000
Writing data to block 182 at offset 0x16c0000
97%3 at offset 0x16e0000
Writing data to block 184 at offset 0x1700000
Writing data to block 185 at offset 0x1720000
Writing data to block 186 at offset 0x1740000
Writing data to block 187 at offset 0x1760000
Writing data to block 188 at offset 0x1780000
Writing data to block 189 at offset 0x17a0000
Writing data to block 190 at offset 0x17c0000
Writing data to block 191 at offset 0x17e0000
Writing data to block 192 at offset 0x1800000
Writing data to block 193 at offset 0x1820000
Writing data to block 194 at offset 0x1840000
Writing data to block 195 at offset 0x1860000
Writing data to block 196 at offset 0x1880000
Writing data to block 197 at offset 0x18a0000
Writing data to block 198 at offset 0x18c0000
Writing data to block 199 at offset 0x18e0000
Writing data to block 200 at offset 0x1900000
Writing data to block 201 at offset 0x1920000
Writing data to block 202 at offset 0x1940000
Writing data to block 203 at offset 0x1960000
Writing data to block 204 at offset 0x1980000
Writing data to block 205 at offset 0x19a0000
Writing data to block 206 at offset 0x19c0000
Writing data to block 207 at offset 0x19e0000
Writing data to block 208 at offset 0x1a00000
Writing data to block 209 at offset 0x1a20000
Writing data to block 210 at offset 0x1a40000
Writing data to block 211 at offset 0x1a60000
Writing data to block 212 at offset 0x1a80000
Writing data to block 213 at offset 0x1aa0000
Writing data to block 214 at offset 0x1ac0000
Writing data to block 215 at offset 0x1ae0000
Writing data to block 216 at offset 0x1b00000
Writing data to block 217 at offset 0x1b20000
Writing data to block 218 at offset 0x1b40000
Writing data to block 219 at offset 0x1b60000
Writing data to block 220 at offset 0x1b80000
Writing data to block 221 at offset 0x1ba0000
Writing data to block 222 at offset 0x1bc0000
Writing data to block 223 at offset 0x1be0000
Writing data to block 224 at offset 0x1c00000
Writing data to block 225 at offset 0x1c20000
Writing data to block 226 at offset 0x1c40000
Writing data to block 227 at offset 0x1c60000
Writing data to block 228 at offset 0x1c80000
Writing data to block 229 at offset 0x1ca0000
Writing data to block 230 at offset 0x1cc0000
Writing data to block 231 at offset 0x1ce0000
Writing data to block 232 at offset 0x1d00000
Writing data to block 233 at offset 0x1d20000
Writing data to block 234 at offset 0x1d40000
Writing data to block 235 at offset 0x1d60000
Writing data to block 236 at offset 0x1d80000
Writing data to block 237 at offset 0x1da0000
Writing data to block 238 at offset 0x1dc0000
Writing data to block 239 at offset 0x1de0000
Writing data to block 240 at offset 0x1e00000
Writing data to block 241 at offset 0x1e20000
Writing data to block 242 at offset 0x1e40000
Writing data to block 243 at offset 0x1e60000
Writing data to block 244 at offset 0x1e80000
Writing data to block 245 at offset 0x1ea0000
Writing data to block 246 at offset 0x1ec0000
Writing data to block 247 at offset 0x1ee0000
Writing data to block 248 at offset 0x1f00000
Writing data to block 249 at offset 0x1f20000
Writing data to block 250 at offset 0x1f40000
Writing data to block 251 at offset 0x1f60000
Writing data to block 252 at offset 0x1f80000
Writing data to block 253 at offset 0x1fa0000
Writing data to block 254 at offset 0x1fc0000
Writing data to block 255 at offset 0x1fe0000
Writing data to block 256 at offset 0x2000000
Writing data to block 257 at offset 0x2020000
Writing data to block 258 at offset 0x2040000
Writing data to block 259 at offset 0x2060000
Writing data to block 260 at offset 0x2080000
Writing data to block 261 at offset 0x20a0000
Writing data to block 262 at offset 0x20c0000
Writing data to block 263 at offset 0x20e0000
Writing data to block 264 at offset 0x2100000
Writing data to block 265 at offset 0x2120000
Writing data to block 266 at offset 0x2140000
Writing data to block 267 at offset 0x2160000
Writing data to block 268 at offset 0x2180000
Writing data to block 269 at offset 0x21a0000
Writing data to block 270 at offset 0x21c0000
Writing data to block 271 at offset 0x21e0000
100%2:31-0000000000000000>Okay (13.24s)
2:31-0000000000000000>Start Cmd:FBK: sync
at offset 0x2200000
Writing data to block 273 at offset 0x2220000
Writing data to block 274 at offset 0x2240000
Writing data to block 275 at offset 0x2260000
Writing data to block 276 at offset 0x2280000
2:31-0000000000000000>Okay (0.038s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nanddtb} 0 0
Erasing 128 Kibyte @ 0 -- 100 % complete
2:31-0000000000000000>Okay (0.015s)
2:31-0000000000000000>Start Cmd:FBK: ucp imx95-19x19-evk.dtb t:/tmp/dtb
100%2:31-0000000000000000>Okay (0.015s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; nandwrite -p /dev/mtd${nanddtb} /tmp/dtb
Writing data to block 0 at offset 0x0
2:31-0000000000000000>Okay (0.047s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; flash_erase /dev/mtd${nandrootfs} 0 0
Erasing 204672 Kibyte @ 0 -- 100 % complete
2:31-0000000000000000>Okay (4.231s)
2:31-0000000000000000>Start Cmd:FBK: ucmd ubidetach /dev/ubi_ctrl -m ${nandrootfs} || true
2:31-0000000000000000>Okay (0.019s)
2:31-0000000000000000>Start Cmd:FBK: ucmd . /tmp/mtd.sh; ubiattach /dev/ubi_ctrl -m ${nandrootfs}
UBI device number 0, total 1599 LEBs (203034624 bytes, 193.6 MiB), available 1555 LEBs (197447680 bytes, 188.3 MiB), LEB size 126976 bytes (124.0 KiB)
2:31-0000000000000000>Okay (0.384s)
2:31-0000000000000000>Start Cmd:FBK: ucmd ubimkvol /dev/ubi0 -N nandrootfs -m
Set volume size to 197447680
Volume ID 0, size 1555 LEBs (197447680 bytes, 188.3 MiB), LEB size 126976 bytes (124.0 KiB), dynamic, name "nandrootfs", alignment 1
2:31-0000000000000000>Okay (0.051s)
2:31-0000000000000000>Start Cmd:FBK: ucmd mkdir -p /mnt/mtd
2:31-0000000000000000>Okay (0.008s)
2:31-0000000000000000>Start Cmd:FBK: ucmd mount -t ubifs ubi0:nandrootfs /mnt/mtd
2:31-0000000000000000>Okay (0.204s)
2:31-0000000000000000>Start Cmd:FBK: acmd export EXTRACT_UNSAFE_SYMLINKS=1; tar --zstd --warning=no-timestamp -x -C /mnt/mtd
2:31-0000000000000000>Okay (0.052s)
2:31-0000000000000000>Start Cmd:FBK: ucp core-image-base-imx95-19x19-lpddr5-evk.rootfs-20260429064745.tar.zst t:-
100%2:31-0000000000000000>Okay (192.3s)
2:31-0000000000000000>Start Cmd:FBK: sync
3. Flashing NOR
The bootloader flashed to NOR must use the newly added imx95_19x19_evk_spinand_defconfig . Therefore, imx95-evk.inc must be modified to enable this.
3.1 UUU Script
uuu_version 1.2.39
# @_flexspi.bin | bootloader
# @_image [_flexspi.bin] | image burn to flexspi, default is the same as bootloader
# This command will be run when i.MX6/7 i.MX8MM, i.MX8MQ
SDP: boot -f .\imx-boot-nor.bin-flash_a55_flexspi
# This command will be run when ROM support stream mode
# i.MX8QXP, i.MX8QM, skip QSPI header
SDPS: boot -f .\imx-boot-nor.bin-flash_a55_flexspi -skipfhdr
# These commands will be run when use SPL and will be skipped if no spl
# SDPU will be deprecated. please use SDPV instead of SDPU
# {
SDPU: delay 1000
SDPU: write -f .\imx-boot-nor.bin-flash_a55_flexspi -offset 0x10000 -skipfhdr
SDPU: jump
# }
# These commands will be run when use SPL and will be skipped if no spl
# if (SPL support SDPV)
# {
SDPV: delay 1000
SDPV: write -f .\imx-boot-nor.bin-flash_a55_flexspi -skipspl -skipfhdr
SDPV: jump
# }
#######################second#################################
FB: ucmd setenv fastboot_buffer ${loadaddr}
FB: download -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi
FB: ucmd if test ! -n "$fastboot_bytes"; then setenv fastboot_bytes $filesize; else true; fi
# Check Image if include flexspi header
FB: ucmd if qspihdr dump ${fastboot_buffer}; then setenv qspihdr_exist yes; else setenv qspihdr_exist no; fi;
# Check Image size if larger than 16M, then use uboot command to write image
FB: ucmd if itest ${fastboot_bytes} -gt 1000000; then setenv qspihdr_large yes; else setenv qspihdr_large no; fi;
FB[-t 60000]: ucmd if test ${qspihdr_exist} = yes -a ${qspihdr_large} = no; then qspihdr init ${fastboot_buffer} ${fastboot_bytes} safe; else true; fi;
#if uboot can't support qspihdr command, use uboot image to write qspi image, which require image include qspi flash header
FB: ucmd if test ${qspihdr_exist} = no; then sf probe; else true; fi;
FB[-t 40000]: ucmd if test ${qspihdr_exist} = no; then sf erase 0 +${fastboot_bytes}; else true; fi;
FB[-t 20000]: ucmd if test ${qspihdr_exist} = no; then sf write ${fastboot_buffer} 0 ${fastboot_bytes}; else true; fi;
# if Image is larger than 16M, use uboot command to write image
FB: ucmd if test ${qspihdr_large} = yes; then sf probe; else true; fi;
FB: write -f .\imx-boot-imx95-19x19-lpddr5-evk-fspi.bin-flash_a55_flexspi -format "if test ${qspihdr_large} = yes; then sf erase @off +@size; sf write ${fastboot_buffer} @off @size; else true; fi;" -blksz 1 -each 0x100000
FB: done
3.2 U-Boot Patches
The functionality implemented is: in the SPL stage, activate NOR FLASH (this is the default code setting), so that uboot.bin can be read from NOR during the SPL stage; then upon entering U-Boot, override the pinctrl settings in the DTB so that the FlexSPI driver uses the NAND pins, and then bring up the NAND on the M.2 connector during U-Boot initialization. imx95_19x19_evk_spinand_defconfig is based on the FSPI defconfig with MTD NAND configuration enabled in U-Boot.
diff --git a/arch/arm/dts/imx95-19x19-evk-spinand.dtsi b/arch/arm/dts/imx95-19x19-evk-spinand.dtsi
new file mode 100644
index 00000000000..20f77d3300b
--- /dev/null
+++ b/arch/arm/dts/imx95-19x19-evk-spinand.dtsi
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2023 NXP
+ */
+
+&flexspi1 {
+ flash1: mt29f4g01abbfd12@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-nand";
+ spi-max-frequency = <80000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+};
diff --git a/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi b/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi
index 3c0c2d7b0f2..0d8fb0c3978 100644
--- a/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx95-19x19-evk-u-boot.dtsi
@@ -182,3 +182,7 @@
assigned-clock-parents = <0>, <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
<&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
};
+
+#ifdef CONFIG_MTD_SPI_NAND
+#include "imx95-19x19-evk-spinand.dtsi"
+#endif
\ No newline at end of file
diff --git a/board/freescale/imx95_evk/imx95_evk.c b/board/freescale/imx95_evk/imx95_evk.c
index 9790c610ac7..147782e94b9 100644
--- a/board/freescale/imx95_evk/imx95_evk.c
+++ b/board/freescale/imx95_evk/imx95_evk.c
@@ -453,6 +453,78 @@ void lvds_backlight_on(void)
dm_i2c_write(dev, 0x8, ®, 1);
}
+
+static int fdt_switch_flexspi_pinctrl_to_nand(void *fdt)
+{
+ int off;
+ const void *prop;
+ int len;
+ int ret;
+ const char *flexspi_path = "/soc/bus@42000000/spi@425e0000";
+
+ off = fdt_path_offset(fdt, flexspi_path);
+ if (off < 0) {
+ printf("FDT: failed to find flexspi node %s, err=%d\n",
+ flexspi_path, off);
+ return off;
+ }
+
+ prop = fdt_getprop(fdt, off, "pinctrl-1", &len);
+ if (!prop || len <= 0) {
+ printf("FDT: no pinctrl-1 found under %s\n", flexspi_path);
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ ret = fdt_setprop(fdt, off, "pinctrl-0", prop, len);
+ if (ret < 0) {
+ printf("FDT: failed to overwrite pinctrl-0, err=%d\n", ret);
+ return ret;
+ }
+
+ printf("FDT: switched %s pinctrl-0 <- pinctrl-1 (NAND)\n",
+ flexspi_path);
+
+ return 0;
+}
+
+static void delete_fdt_flash0(void *fdt)
+{
+ int i = 0;
+ int nodeoff, ret;
+ static const char * const spi_nodes[] = {
+ "/soc/bus@42000000/spi@425e0000/flash@0"
+ };
+
+ printf("delete_fdt_flash0\n");
+
+ for (i = 0; i < ARRAY_SIZE(spi_nodes); i++) {
+ nodeoff = fdt_path_offset(fdt, spi_nodes[i]);
+ if (nodeoff >= 0) {
+delete_node:
+ ret = fdt_del_node(fdt, nodeoff);
+ if (ret == -FDT_ERR_NOSPACE) {
+ ret = fdt_increase_size(fdt, 512);
+ if (!ret) {
+ nodeoff = fdt_path_offset(fdt, spi_nodes[i]);
+ if (nodeoff >= 0)
+ goto delete_node;
+ }
+ }
+
+ if (ret)
+ printf("failed to delete node %s, ret=%d\n",
+ spi_nodes[i], ret);
+ else
+ printf("deleted node %s\n", spi_nodes[i]);
+ }
+ }
+}
+static void fdt_fixup_flexspi(void *fdt)
+{
+ delete_fdt_flash0(fdt);
+ fdt_switch_flexspi_pinctrl_to_nand(fdt);
+}
+
int board_init(void)
{
int ret;
@@ -475,17 +547,53 @@ int board_init(void)
netc_init();
- flexspi_nor_steup();
+ // flexspi_nor_steup();
power_on_m7("mx95evkrpmsg");
+ printf("board_init\n");
+
lvds_backlight_on();
return 0;
}
+#include <dm.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+
+static void debug_probe_fspi_nand(void)
+{
+ struct udevice *bus;
+ struct udevice *child;
+ int ret;
+
+ printf("debug_probe_fspi_nand: start\n");
+
+ ret = uclass_get_device_by_name(UCLASS_SPI, "spi@425e0000", &bus);
+ printf("get spi bus ret=%d, bus=%p\n", ret, bus);
+ if (ret)
+ return;
+
+ ret = device_probe(bus);
+ printf("probe spi bus ret=%d\n", ret);
+
+ child = NULL;
+ device_find_first_child(bus, &child);
+ while (child) {
+ printf("child name=%s\n", child->name);
+ ret = device_probe(child);
+ printf("probe child %s ret=%d\n", child->name, ret);
+ device_find_next_child(&child);
+ }
+
+ printf("debug_probe_fspi_nand: done\n");
+}
+
int board_late_init(void)
{
+ printf("board_late_init\n");
+ debug_probe_fspi_nand();
if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
board_late_mmc_env_init();
@@ -645,6 +753,8 @@ static int board_fix_19x19_evk(void *fdt)
int ret;
const char *netcfg = "mx95netc";
+ fdt_fixup_flexspi(fdt);
+
ret = scmi_misc_cfginfo(&msel, cfgname);
if (!ret) {
debug("SM: %s\n", cfgname);
diff --git a/configs/imx95_19x19_evk_spinand_defconfig b/configs/imx95_19x19_evk_spinand_defconfig
new file mode 100644
index 00000000000..77077341412
--- /dev/null
+++ b/configs/imx95_19x19_evk_spinand_defconfig
@@ -0,0 +1,264 @@
+CONFIG_ARM=y
+CONFIG_ARCH_IMX9=y
+CONFIG_TEXT_BASE=0x90200000
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_SYS_MALLOC_F_LEN=0x10000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=3
+CONFIG_ENV_SOURCE_FILE="imx95_evk"
+CONFIG_SF_DEFAULT_SPEED=200000000
+CONFIG_ENV_SIZE=0x4000
+CONFIG_ENV_OFFSET=0x700000
+CONFIG_ENV_SECT_SIZE=0x20000
+CONFIG_IMX_CONFIG="arch/arm/mach-imx/imx9/scmi/imximage.cfg"
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="imx95-19x19-evk-rm692c9-adv7535"
+CONFIG_USB_TCPC=y
+CONFIG_TARGET_IMX95_19X19_EVK=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_SYS_MONITOR_LEN=524288
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_STACK=0x204d6000
+CONFIG_SPL_TEXT_BASE=0x20480000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x204d6000
+CONFIG_SPL_BSS_MAX_SIZE=0x2000
+CONFIG_SYS_LOAD_ADDR=0x90400000
+CONFIG_SPL=y
+CONFIG_SPL_RECOVER_DATA_SECTION=y
+CONFIG_PCI=y
+CONFIG_SYS_MEMTEST_START=0x90000000
+CONFIG_SYS_MEMTEST_END=0xA0000000
+CONFIG_REMAKE_ELF=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_SYSTEM_SETUP=y
+# CONFIG_BOOTCOMMAND="bootflow scan -l; run bsp_bootcmd"
+CONFIG_DEFAULT_FDT_FILE="imx95-19x19-evk-adv7535-ap1302.dtb"
+CONFIG_SYS_CBSIZE=2048
+CONFIG_SYS_PBSIZE=2074
+CONFIG_ARCH_MISC_INIT=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_SPL_MAX_SIZE=0x30000
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_LOAD_IMX_CONTAINER=y
+CONFIG_IMX_CONTAINER_CFG="arch/arm/mach-imx/imx9/scmi/container.cfg"
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_SYS_MALLOC=y
+CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
+CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x93200000
+CONFIG_SPL_SYS_MALLOC_SIZE=0x80000
+CONFIG_SPL_SYS_MMCSD_RAW_MODE=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1040
+CONFIG_SPL_I2C=y
+CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_DM_SPI=y
+CONFIG_SPL_DM_SPI_FLASH=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SPL_SPI_FLASH_TINY=n
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x200000
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_POWER=y
+CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_USB_SDP_SUPPORT=y
+CONFIG_SDP_LOADADDR=0x90400000
+
+CONFIG_SPL_WATCHDOG=y
+CONFIG_SYS_PROMPT="u-boot=> "
+CONFIG_CMD_ERASEENV=y
+CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_CRC32=y
+CONFIG_CRC32_VERIFY=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_FUSE=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EFIDEBUG=y
+CONFIG_CMD_RTC=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_GETTIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_HASH=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_USB_SDP=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_OF_BOARD_FIXUP=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_NOWHERE=y
+# CONFIG_ENV_IS_IN_MMC=y
+# CONFIG_ENV_IS_IN_SPI_FLASH=y
+###################NAND###########################
+CONFIG_ENV_IS_IN_UBI=y
+CONFIG_MTD_UBI=y
+CONFIG_CMD_UBI=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:8m(bootloader)ro,8m(config),40m(kernel),128k(dtb),-(rootfs)"
+CONFIG_ENV_UBI_PART="config"
+CONFIG_ENV_UBI_VOLUME="uboot-env"
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyLP0,115200 earlycon ubi.mtd=4 root=ubi0:nandrootfs rootfstype=ubifs rootwait rw mtdparts=spi0.0:8m(bootloader)ro,8m(config),40m(kernel),128k(dtb),-(rootfs)"
+CONFIG_BOOTCOMMAND="mtd read kernel $loadaddr 0 0x2400000 && mtd read dtb $fdt_addr 0 0x20000 && booti $loadaddr - $fdt_addr"
+###################################################
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_USE_ETHPRIME=y
+CONFIG_ETHPRIME="eth0"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYS_RX_ETH_BUFFER=8
+CONFIG_SPL_DM=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_SPL_CLK_CCF=y
+CONFIG_CLK_CCF=y
+CONFIG_CLK_SCMI=y
+CONFIG_SPL_CLK_SCMI=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_SPL_FIRMWARE=y
+# CONFIG_SCMI_AGENT_SMCCC is not set
+CONFIG_IMX_RGPIO2P=y
+
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_SOFT_RESET=y
+CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y
+
+CONFIG_CMD_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_UUU_SUPPORT=y
+CONFIG_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x92800000
+CONFIG_FASTBOOT_BUF_SIZE=0x20000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_EFI_PARTITION=y
+CONFIG_FASTBOOT_USB_DEV=0
+CONFIG_USB_PORT_AUTO=y
+
+CONFIG_DM_PCA953X=y
+CONFIG_ADP5585_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_IMX_LPI2C=y
+CONFIG_IMX_MU_MBOX=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_ES_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_FSL_USDHC=y
+CONFIG_CMD_NAND=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+# CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MT35XU=y
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_10G=y
+CONFIG_PHY_AQUANTIA=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DM_MDIO=y
+CONFIG_MII=y
+CONFIG_FSL_ENETC=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_PHY=y
+CONFIG_PHY_IMX8MQ_USB=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_IMX_SCMI=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_SCMI_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_RTC=y
+CONFIG_DM_SERIAL=y
+CONFIG_FSL_LPUART=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_NXP_FSPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MAX_CONTROLLER_COUNT=2
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="FSL"
+CONFIG_USB_GADGET_VENDOR_NUM=0x1fc9
+CONFIG_USB_GADGET_PRODUCT_NUM=0x0152
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_ULP_WATCHDOG=y
+CONFIG_LZO=y
+CONFIG_BZIP2=y
+CONFIG_OF_BOARD_SETUP=y
+
+CONFIG_IMX_SNPS_DDR_PHY_QB_GEN=y
+CONFIG_SAVED_QB_STATE_BASE=0x4aaf0000
+
+CONFIG_DM_THERMAL=y
+CONFIG_SCMI_THERMAL=y
+CONFIG_SPL_THERMAL=y
+
+CONFIG_VIDEO_IMX95_DPU=y
+CONFIG_VIDEO_IMX95_DW_DSI=y
+CONFIG_VIDEO_IMX95_PIXEL_LINK=y
+CONFIG_VIDEO_IMX95_PIXEL_INTERLEAVER=y
+CONFIG_VIDEO=y
+CONFIG_BMP_16BPP=y
+CONFIG_BMP_24BPP=y
+CONFIG_BMP_32BPP=y
+CONFIG_VIDEO_LOGO=y
+CONFIG_VIDEO_LCD_RAYDIUM_RM692C9=y
+CONFIG_VIDEO_ADV7535=y
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_SPLASH_SCREEN=y
+CONFIG_SPLASH_SCREEN_ALIGN=y
+CONFIG_CMD_BMP=y
+CONFIG_DISPLAY=y
+CONFIG_MIPI_DPHY_HELPERS=y
+
+CONFIG_BOOTDEV_ETH=n
+CONFIG_DM_RNG=y
+CONFIG_IMX_ELE_RNG=y
+CONFIG_ELE_SHARED_BUFFER=0x98000000
+
+CONFIG_PCIE_DW_IMX=y
+CONFIG_NVME=y
+CONFIG_NVME_PCI=y
+CONFIG_CMD_NVME=y
+CONFIG_CLK_IMX95_BLKCTRL=y
diff --git a/drivers/spi/nxp_fspi.c b/drivers/spi/nxp_fspi.c
index 078b97f6544..07fb96cbfcc 100644
--- a/drivers/spi/nxp_fspi.c
+++ b/drivers/spi/nxp_fspi.c
@@ -1177,6 +1177,7 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
static int nxp_fspi_probe(struct udevice *bus)
{
+ printf("------------>nxp_fspi_probe\n");
struct nxp_fspi *f = dev_get_priv(bus);
f->devtype_data =
@@ -1241,6 +1242,7 @@ static int nxp_fspi_of_to_plat(struct udevice *bus)
#if CONFIG_IS_ENABLED(CLK)
int ret;
#endif
+ printf("------------>nxp_fspi_of_to_plat\n");
fdt_addr_t iobase;
fdt_addr_t iobase_size;
diff --git a/dts/upstream/src/arm64/freescale/imx95-19x19-evk.dts b/dts/upstream/src/arm64/freescale/imx95-19x19-evk.dts
index 6086cb7fa5a..7d5fd3500ff 100644
--- a/dts/upstream/src/arm64/freescale/imx95-19x19-evk.dts
+++ b/dts/upstream/src/arm64/freescale/imx95-19x19-evk.dts
@@ -194,11 +194,12 @@
};
&flexspi1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "nand";
pinctrl-0 = <&pinctrl_flexspi1>;
+ pinctrl-1 = <&pinctrl_flexspi1_nand>;
status = "okay";
- flash@0 {
+ flash0: flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
pinctrl-names = "default";
@@ -445,6 +446,17 @@
>;
};
+ pinctrl_flexspi1_nand: flexspi1nandgrp {
+ fsl,pins = <
+ IMX95_PAD_SD3_CMD__FLEXSPI1_A_SS0_B 0x3fe
+ IMX95_PAD_SD3_CLK__FLEXSPI1_A_SCLK 0x3fe
+ IMX95_PAD_SD3_DATA0__FLEXSPI1_A_DATA_BIT0 0x3fe
+ IMX95_PAD_SD3_DATA1__FLEXSPI1_A_DATA_BIT1 0x3fe
+ IMX95_PAD_SD3_DATA2__FLEXSPI1_A_DATA_BIT2 0x3fe
+ IMX95_PAD_SD3_DATA3__FLEXSPI1_A_DATA_BIT3 0x3fe
+ >;
+ };
+
pinctrl_flexspi1_reset: flexspi1-reset-grp {
fsl,pins = <
IMX95_PAD_XSPI1_SS1_B__GPIO5_IO_BIT11 0x3fe
3.3 imx95-evk.inc Content
require conf/machine/include/imx-base.inc
require conf/machine/include/arm/armv8-2a/tune-cortexa55.inc
MACHINE_FEATURES += "pci wifi bluetooth optee"
MACHINE_FEATURES:append:use-nxp-bsp = " nxpwifi-all-pcie nxpwifi-all-sdio jailhouse dpdk xen"
KERNEL_DEVICETREE = " \
freescale/${KERNEL_DEVICETREE_BASENAME}.dtb \
"
UBOOT_DTB_NAME = "${KERNEL_DEVICETREE_BASENAME}.dtb"
IMX_DEFAULT_BOOTLOADER:use-nxp-bsp = "u-boot-imx"
IMX_DEFAULT_BOOTLOADER:use-mainline-bsp = "u-boot-fslc"
LOADADDR = ""
UBOOT_SUFFIX = "bin"
UBOOT_MAKE_TARGET = ""
SPL_BINARY = "spl/u-boot-spl.bin"
UBOOT_CONFIG ??= "sd"
UBOOT_CONFIG[sd] = "${UBOOT_CONFIG_BASENAME}_defconfig,sdcard"
UBOOT_CONFIG[sd-ecc] = "${UBOOT_CONFIG_BASENAME}_defconfig,sdcard"
UBOOT_CONFIG[fspi] = "${UBOOT_CONFIG_BASENAME}_spinand_defconfig"///////////////////here
UBOOT_CONFIG[spinand] = "${UBOOT_CONFIG_BASENAME}_spinand_defconfig"////////////////here
ATF_PLATFORM = "imx95"
OEI_CORE = "m33"
OEI_SOC = "mx95"
OEI_BOARD ?= "mx95lp5"
DDR_TYPE ?= "lpddr5"
IMXBOOT_VARIANTS = "alt jailhouse netc rpmsg sof"
# Multiple system manager configs by IMXBOOT_VARIANT
SYSTEM_MANAGER_CONFIG = \
"${@bb.utils.contains('IMXBOOT_VARIANT', 'alt', 'mx95alt', \
bb.utils.contains('IMXBOOT_VARIANT', 'jailhouse', 'mx95evkjailhouse', \
bb.utils.contains('IMXBOOT_VARIANT', 'netc', 'mx95netc', \
bb.utils.contains('IMXBOOT_VARIANT', 'rpmsg', 'mx95evkrpmsg', \
bb.utils.contains('IMXBOOT_VARIANT', 'sof', 'mx95evksof', \
'mx95evk', d), d), d), d), d)}"
# imx-boot (flash.bin) targets based on UBOOT_CONFIG and IMXBOOT_VARIANT
IMXBOOT_TARGETS_SD = " \
${@bb.utils.contains('IMXBOOT_VARIANT', 'alt', '${IMXBOOT_TARGETS_BASENAME}_alt', \
bb.utils.contains('IMXBOOT_VARIANT', 'jailhouse', '${IMXBOOT_TARGETS_BASENAME}_jailhouse', \
bb.utils.contains('IMXBOOT_VARIANT', 'netc', '${IMXBOOT_TARGETS_BASENAME}_netc', \
bb.utils.contains('IMXBOOT_VARIANT', 'rpmsg', '${IMXBOOT_TARGETS_BASENAME}_lpboot_sm_a55', \
bb.utils.contains('IMXBOOT_VARIANT', 'sof', '${IMXBOOT_TARGETS_BASENAME}_a55', \
'${IMXBOOT_TARGETS_BASENAME}_all ${IMXBOOT_TARGETS_BASENAME}_a55', d), d), d), d), d)} \
"
IMXBOOT_TARGETS = " \
${@bb.utils.contains('UBOOT_CONFIG', 'fspi', '${IMXBOOT_TARGETS_BASENAME}_a55_flexspi', \
bb.utils.contains('UBOOT_CONFIG', 'sd-ecc', '${IMXBOOT_TARGETS_BASENAME}_all', \
'${IMXBOOT_TARGETS_SD}', d), d)} \
"
IMX_BOOT_SOC_TARGET = "iMX95"
IMX_BOOT_SEEK = "32"
# We have to disable SERIAL_CONSOLE due to auto-serial-console
SERIAL_CONSOLES = "115200;ttyLP0"
IMX_DEFAULT_BSP = "nxp"
4. NOR Boot Test
After NOR boot, U-Boot activates the NAND on the M.2 connector, successfully reads the kernel and device tree from NAND. After entering the kernel, the rootfs is successfully mounted.
U-Boot SPL 2025.04-g4ddbad60eff3-dirty (Mar 19 2026 - 03:13:58 +0000)
SYS Boot reason: por, origin: -1, errid: -1
SYS shutdown reason: por, origin: -1, errid: -1
Normal Boot
Trying to boot from SPI
------------>nxp_fspi_of_to_plat
------------>nxp_fspi_probe
Boot stage: Primary
Image set: 0, offset: 0x1000
Load image from QSPI 0xde400------------------------------->NOR BOOT
NOTICE: BL31: v2.12.0(release):lf-6.12.49-2.2.0
NOTICE: BL31: Built : 10:35:59, Apr 21 2026
U-Boot 2025.04-g4ddbad60eff3-dirty (Mar 19 2026 - 03:13:58 +0000)
CPU: i.MX9596 rev2.0 at 1800MHz
CPU: Extended Industrial temperature grade (-40C to 125C) at 28C
LM Boot reason: por, origin: -1, errid: -1
LM shutdown reason: por, origin: -1, errid: -1
Model: NXP i.MX95 19X19 board
DRAM: delete_fdt_flash0
deleted node /soc/bus@42000000/spi@425e0000/flash@0
FDT: switched /soc/bus@42000000/spi@425e0000 pinctrl-0 <- pinctrl-1 (NAND)
15.8 GiB
TCPC: Vendor ID [0x1fc9], Product ID [0x5110], Addr [I2C6 0x50]
PCIE-2: Link down
PCIE-3: Link down
cfg name not match mx95evkrpmsg:mx95evk, ignore
board_init
Core: 317 devices, 38 uclasses, devicetree: separate
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from nowhere... OK
[*]-Video Link 0clk disp1pix already disabled
adv7535_mipi2hdmi hdmi@3d: Can't find cec device id=0x3c
fail to probe panel device hdmi@3d
probe video device failed, ret -19
[0] display-controller@4b400000, video
[1] channel@0, video_bridge
[2] bridge@8, video_bridge
[3] dsi@4acf0000, video_bridge
[4] hdmi@3d, panel
clk disp1pix already disabled
adv7535_mipi2hdmi hdmi@3d: Can't find cec device id=0x3c
fail to probe panel device hdmi@3d
probe video device failed, ret -19
In: serial
Out: serial
Err: serial
BuildInfo:
- SM firmware Build 763, Commit de30901b, Apr 15 2026 01:18:07
- ELE firmware version 2.0.4-9ca4d997
board_late_init
debug_probe_fspi_nand: start
------------>nxp_fspi_of_to_plat
------------>nxp_fspi_probe
get spi bus ret=0, bus=00000000fd4a13d0
probe spi bus ret=0
child name=mt29f4g01abbfd12@0
probe child mt29f4g01abbfd12@0 ret=0----------------->SWITCH TO NAND
debug_probe_fspi_nand: done
UID: 182ba9e87d9840babd9d12161b48e82d
Net: eth0: enetc-0 [PRIME], eth1: enetc-2
Fastboot: Normal
Normal Boot
Hit any key to stop autoboot: 0
u-boot=> setenv bootargs 'console=ttyLP0,115200 earlycon ubi.mtd=rootfs root=ubi0:nandrootfs rootfstype=ubifs rootwait rw'
u-boot=> mtd read kernel ${loadaddr} 0 0x2800000
Reading 41943040 byte(s) (20480 page(s)) at offset 0x00000000
u-boot=> mtd read dtb ${fdt_addr} 0 0x20000
Reading 131072 byte(s) (64 page(s)) at offset 0x00000000
u-boot=> booti ${loadaddr} - ${fdt_addr} ------------------>read kernel, dtb in NAND
## Flattened Device Tree blob at 93000000
Booting using the fdt blob at 0x93000000
Working FDT set to 93000000
Loading Device Tree to 000000009ffe5000, end 000000009ffffeaf ... OK
Working FDT set to 9ffe5000
clk disp1pix already disabled
adv7535_mipi2hdmi hdmi@3d: Can't find cec device id=0x3c
fail to probe panel device hdmi@3d
probe video device failed, ret -19
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x412fd050]
[ 0.000000] Linux version 6.18.2-1.0.0-gf49f45233f7b-dirty (oe-user@oe-host) (aarch64-poky-linux-gcc (GCC) 15.2.0, GNU ld (GNU Binutils) 2.45.0.20250908) #1 SMP PREEMPT Tue Apr 28 08:20:17 UTC 2026
[ 0.000000] KASLR enabled
[ 0.000000] Machine model: NXP i.MX95 19X19 board
[ 0.000000] efi: UEFI not found.
[ 0.000000] Reserved memory: created CMA memory pool at 0x00000000c3000000, size 960 MiB
[ 0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
[ 0.000000] OF: reserved mem: 0x00000000c3000000..0x00000000feffffff (983040 KiB) map reusable linux,cma
[ 0.000000] earlycon: lpuart32 at MMIO32 0x0000000044380000 (options '')
...................
[ 2.416067] spi-nand spi1.0: Winbond SPI NAND was found.
[ 2.428075] spi-nand spi1.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
[ 2.450050] 5 fixed-partitions partitions found on MTD device spi1.0
[ 2.450059] Creating 5 MTD partitions on "spi1.0":
[ 2.463548] 0x000000000000-0x000000800000 : "bootloader"
[ 2.529065] 0x000000800000-0x000001000000 : "config"
[ 2.543539] 0x000001000000-0x000003800000 : "kernel"
[ 2.580906] 0x000003800000-0x000003820000 : "dtb"
[ 2.586513] 0x000003820000-0x00010381ffff : "rootfs"
[ 2.591493] mtd: partition "rootfs" extends beyond the end of device "spi1.0" -- size truncated to 0xc7e0000
[ 2.748893] mtd: setting mtd4 (rootfs) as root device
[ 4.909898] ubi0: attaching mtd4
[ 5.406361] ubi0: scanning is finished
[ 5.454338] ubi0: attached mtd4 (name "rootfs", size 199 MiB)
[ 5.460134] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[ 5.467131] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[ 5.473950] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[ 5.480935] ubi0: good PEBs: 1599, bad PEBs: 0, corrupted PEBs: 0
[ 5.487037] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
[ 5.494255] ubi0: max/mean erase counter: 10/1, WL threshold: 4096, image sequence number: 2909496578
[ 5.503473] ubi0: available PEBs: 0, total reserved PEBs: 1599, PEBs reserved for bad PEB handling: 40
[ 5.512840] ubi0: background thread "ubi_bgt0d" started, PID 135
[ 5.594576] UBIFS (ubi0:0): Mounting in unauthenticated mode
[ 5.600411] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 141
[ 5.617312] UBIFS (ubi0:0): recovery needed
[ 5.801795] UBIFS (ubi0:0): recovery completed
[ 5.806343] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "nandrootfs"
[ 5.814101] UBIFS (ubi0:0): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[ 5.824021] UBIFS (ubi0:0): FS size: 195923968 bytes (186 MiB, 1543 LEBs), max 1555 LEBs, journal size 9777152 bytes (9 MiB, 77 LEBs)
[ 5.836024] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
[ 5.842640] UBIFS (ubi0:0): media format: w5/r0 (latest is w5/r0), UUID 02E616B2-3C31-4F48-A886-9B4D26DB37C1, small LPT model
[ 5.854616] VFS: Mounted root (ubifs filesystem) on device 0:23.
[ 5.860973] devtmpfs: mounted
[ 5.864349] Freeing unused kernel memory: 2112K
[ 5.868991] Run /sbin/init as init process
[ 5.874243] Run /etc/init as init process
[ 5.879058] Run /bin/init as init process
[ 5.884114] Run /bin/sh as init process
記事全体を表示