]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
binman: imx8mimage: Generate FSPI header in binman instead of mkimage
authorMarek Vasut <marex@nabladev.com>
Sun, 5 Jul 2026 21:19:05 +0000 (23:19 +0200)
committerFabio Estevam <festevam@gmail.com>
Mon, 27 Jul 2026 14:30:25 +0000 (11:30 -0300)
Stop depending on the current mkimage method of generating the FSPI
header, instead generate the FSPI header within binman itself. This
is more flexible, as the FSPI header properties can be configured
from within the board-specific DT instead of being hard-coded in
mkimage at build time.

Acked-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
tools/binman/etype/nxp_imx8mimage.py
tools/binman/ftest.py
tools/binman/test/vendor/nxp_imx8m_fspi.dts
tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts [new file with mode: 0644]
tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts [moved from tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts with 83% similarity]
tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts [new file with mode: 0644]
tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts [new file with mode: 0644]
tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts [new file with mode: 0644]
tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts

index 25c43438a872a3faf7948c67a7940504277ac3d4..38d31b1bc09f6e7c4ec730e9d0cd183e71ad4e69 100644 (file)
@@ -7,7 +7,7 @@
 # configuration file and input data.
 #
 
-import os
+import struct
 
 from collections import OrderedDict
 
@@ -25,8 +25,26 @@ class Entry_nxp_imx8mimage(Entry_mkimage):
         - nxp,boot-from - device to boot from (e.g. 'sd')
         - nxp,loader-address - loader address (SPL text base)
         - nxp,rom-version - BootROM version ('2' for i.MX8M Nano and Plus)
-        - nxp,fspi-header-filename - FSPI header file name (CONFIG_FSPI_CONF_FILE).
-            Used only if 'nxp,boot-from == "fspi"' .
+
+    Properties / Entry arguments for FSPI boot mode (nxp,boot-from = "fspi"):
+        - nxp,fspi-columnaddresswidth - FSPI column address width
+            (3 - HyperFlash, 12/13 - Serial NAND, 0 - Otherwise (default))
+        - nxp,fspi-controllermisc-diffclk - FSPI differential clock enable (default off)
+        - nxp,fspi-controllermisc-wordaddr - FSPI word addressable enable (default off)
+        - nxp,fspi-controllermisc-safecfg - FSPI safe configuration frequency (default off)
+        - nxp,fspi-controllermisc-padovr - FSPI pad setting override (default off)
+        - nxp,fspi-controllermisc-ddrmode - FSPI DDR mode (default off)
+        - nxp,fspi-lutcustomseq - FSPI use LUT sequence parameters (default off)
+        - nxp,fspi-devicetype - FSPI device type
+            (1 - SPI NOR (default), 2 - Serial NAND)
+        - nxp,fspi-flasha1size - FSPI device size (default 0x10000000)
+        - nxp,fspi-flashpadtype - FSPI flash pad type
+            (1 - Single pad (default), 2 - Dual pads, 4 - Quad pads, 8 - Octal pads)
+        - nxp,fspi-readsampleclksrc - FSPI clock source
+            (0 - Internal loopback (default), 1 - loopback from DQS pad, 3 - Flash provided DQS).
+        - nxp,fspi-serialclkfreq - FSPI clock frequency
+            (1 - 30 MHz, 2 - 50 MHz (default), 3 - 60 MHz, 4 - 75 MHz, 5 - 80 MHz,
+             6 - 100 MHz, 7 - 133 MHz, 8 - 166 MHz).
     """
 
     def __init__(self, section, etype, node):
@@ -37,9 +55,30 @@ class Entry_nxp_imx8mimage(Entry_mkimage):
     def ReadNode(self):
         super().ReadNode()
         self.boot_from = fdt_util.GetString(self._node, 'nxp,boot-from')
-        self.fspi_header = fdt_util.GetString(self._node, 'nxp,fspi-header-filename', 'fspi_header.bin')
+        self.fspi_columnadresswidth = fdt_util.GetInt(self._node, 'nxp,fspi-columnaddresswidth', 0)
+        self.fspi_controllermisc_diffclk = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-diffclk')
+        self.fspi_controllermisc_wordaddr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-wordaddr')
+        self.fspi_controllermisc_safecfg = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-safecfg')
+        self.fspi_controllermisc_padovr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-padovr')
+        self.fspi_controllermisc_ddrmode = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-ddrmode')
+        self.fspi_devicetype = fdt_util.GetInt(self._node, 'nxp,fspi-devicetype', 1)
+        self.fspi_flasha1size = fdt_util.GetInt(self._node, 'nxp,fspi-flasha1size', 0x10000000)
+        self.fspi_flashpadtype = fdt_util.GetInt(self._node, 'nxp,fspi-flashpadtype', 1)
+        self.fspi_lutcustomseq = fdt_util.GetBool(self._node, 'nxp,fspi-lutcustomseq')
+        self.fspi_readsampleclksrc = fdt_util.GetInt(self._node, 'nxp,fspi-readsampleclksrc', 0)
+        self.fspi_serialclkfreq = fdt_util.GetInt(self._node, 'nxp,fspi-serialclkfreq', 2)
         self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address')
         self.rom_version = fdt_util.GetInt(self._node, 'nxp,rom-version')
+        if not self.fspi_columnadresswidth in [ 0, 3, 12, 13 ]:
+            self.Raise('nxp,fspi-columnaddresswidth can be 0, 3, 12, 13 only.')
+        if not self.fspi_devicetype in [ 1, 2 ]:
+            self.Raise('nxp,fspi-devicetype can be 1, 2 only.')
+        if not self.fspi_flashpadtype in [ 1, 2, 4, 8 ]:
+            self.Raise('nxp,fspi-flashpadtype can be 1, 2, 4, 8 only.')
+        if not self.fspi_readsampleclksrc in [ 0, 1, 3 ]:
+            self.Raise('nxp,fspi-readsampleclksrc can be 0, 1, 3 only.')
+        if not self.fspi_serialclkfreq in [ 1, 2, 3, 4, 5, 6, 7, 8 ]:
+            self.Raise('nxp,fspi-serialclkfreq can be 1..8 only.')
         self.ReadEntries()
 
     def BuildSectionData(self, required):
@@ -59,9 +98,51 @@ class Entry_nxp_imx8mimage(Entry_mkimage):
         if self.mkimage.run_cmd(*args) is not None:
             outdata = tools.read_file(output_fname)
             if self.boot_from == 'fspi':
-                spidata = tools.read_file(os.path.join(tools.get_output_dir(), self.fspi_header))
-                if len(spidata) != 448:
-                    raise ValueError("FSPI header is not 448 Bytes long")
+                # 0x00 ... Tag
+                spidata = struct.pack('<I', 0x42464346)
+                # 0x04 ... Version
+                spidata += struct.pack('<I', 0x56010000)
+                # 0x08 ... Reserved
+                spidata += struct.pack('<I', 0)
+                # 0x0c ... readSampleClkSrc (LSByte at 0x0c), dataHoldTime,
+                #          dataSetupTime, columnAdressWidth (MSByte at 0x0f)
+                spidata += struct.pack('<I', 0x00030300 |
+                    (self.fspi_columnadresswidth << 24) |
+                    self.fspi_readsampleclksrc)
+
+                # 0x10..0x3f ... Padding
+                spidata += tools.get_bytes(0, 0x30)
+
+                # 0x40 ... controllerMiscOption
+                spidata += struct.pack('<I',
+                    ((1 << 0) if self.fspi_controllermisc_diffclk else 0) |
+                    ((1 << 3) if self.fspi_controllermisc_wordaddr else 0) |
+                    ((1 << 4) if self.fspi_controllermisc_safecfg else 0) |
+                    ((1 << 5) if self.fspi_controllermisc_padovr else 0) |
+                    ((1 << 6) if self.fspi_controllermisc_ddrmode else 0))
+
+                # 0x44 ... deviceType (LSByte at 0x44), sflashPadType,
+                #          serialClkFreq, lutCustomSeqEnable (MSByte at 0x47)
+                spidata += struct.pack('<I',
+                    ((1 << 24) if self.fspi_lutcustomseq else 0) |
+                    (self.fspi_serialclkfreq << 16) |
+                    (self.fspi_flashpadtype << 8) |
+                    self.fspi_devicetype)
+
+                # 0x48..0x4f ... Padding
+                spidata += tools.get_bytes(0, 0x8)
+
+                # 0x50 ... flashA1Size
+                spidata += struct.pack('<I', self.fspi_flasha1size)
+
+                # 0x54..0x7f ... Padding
+                spidata += tools.get_bytes(0, 0x2c)
+
+                # 0x80 ... lookupTable
+                spidata += struct.pack('<I', 0x0818040b)
+                spidata += struct.pack('<I', 0x24043008)
+
+                # 0x88..0xfff ... Padding (end of FSPI block is 0x1bf, align to 4k)
                 spidata += tools.get_bytes(0, 0x1000 - len(spidata))
                 outdata = spidata + outdata
             return outdata
index ea2fa6eb83ac6bdc27ada9ecf87af5d0d29df033..875c94b08ee57c1d39395b445b58e9b80d61ae85 100644 (file)
@@ -8106,17 +8106,18 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
 
     def testNxpImx8MFSPI(self):
         """Test that binman can produce an iMX8m FSPI image"""
-        testdir = tempfile.mkdtemp(prefix='binman.')
-
-        tools.write_file(os.path.join(testdir, 'fspi_header.bin'), tools.get_bytes(0, 448))
-        with terminal.capture():
-            self._DoTestFile('vendor/nxp_imx8m_fspi.dts', output_dir=testdir)
-            self._DoTestFile('vendor/nxp_imx8m_fspi_pass.dts', output_dir=testdir)
-
-        tools.write_file(os.path.join(testdir, 'fspi_header_fail.bin'), tools.get_bytes(0, 4097))
-        with terminal.capture():
-            with self.assertRaises(ValueError) as e:
-                self._DoTestFile('vendor/nxp_imx8m_fspi_fail.dts', output_dir=testdir)
+        self._DoTestFile('vendor/nxp_imx8m_fspi.dts')
+        self._DoTestFile('vendor/nxp_imx8m_fspi_pass.dts')
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile('vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts')
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile('vendor/nxp_imx8m_fspi_fail_devicetype.dts')
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile('vendor/nxp_imx8m_fspi_fail_flashpadtype.dts')
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile('vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts')
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile('vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts')
 
     def testNxpHeaderDdrfw(self):
         """Test that binman can add a header to DDR PHY firmware images"""
index ae6cc5981e657359edc14f3d0a4a7437e7c079d6..140e9bea2e741822522fd925a15d8b533ee84705 100644 (file)
@@ -10,7 +10,6 @@
                nxp-imx8mimage {
                        args;   /* TODO: Needed by mkimage etype superclass */
                        nxp,boot-from = "fspi";
-                       nxp,fspi-header-filename = "fspi_header.bin";
                        nxp,rom-version = <1>;
                        nxp,loader-address = <0x10>;
                };
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts
new file mode 100644 (file)
index 0000000..95efa33
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               nxp-imx8mimage {
+                       args;   /* TODO: Needed by mkimage etype superclass */
+                       nxp,boot-from = "fspi";
+                       nxp,rom-version = <2>;
+                       nxp,loader-address = <0x10>;
+                       /* Bogus value */
+                       nxp,fspi-columnaddresswidth = <1>;
+               };
+       };
+};
similarity index 83%
rename from tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts
rename to tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts
index 5a0d758e5a3f893ef457967025715738e9badad4..f3b343f942f415b88b3a4d756d43362dcb0ee969 100644 (file)
                nxp-imx8mimage {
                        args;   /* TODO: Needed by mkimage etype superclass */
                        nxp,boot-from = "fspi";
-                       nxp,fspi-header-filename = "fspi_header_fail.bin";
                        nxp,rom-version = <2>;
                        nxp,loader-address = <0x10>;
+                       /* Bogus value */
+                       nxp,fspi-devicetype = <3>;
                };
        };
 };
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts
new file mode 100644 (file)
index 0000000..515f81b
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               nxp-imx8mimage {
+                       args;   /* TODO: Needed by mkimage etype superclass */
+                       nxp,boot-from = "fspi";
+                       nxp,rom-version = <2>;
+                       nxp,loader-address = <0x10>;
+                       /* Bogus value */
+                       nxp,fspi-flashpadtype = <9>;
+               };
+       };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts
new file mode 100644 (file)
index 0000000..b409a60
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               nxp-imx8mimage {
+                       args;   /* TODO: Needed by mkimage etype superclass */
+                       nxp,boot-from = "fspi";
+                       nxp,rom-version = <2>;
+                       nxp,loader-address = <0x10>;
+                       /* Bogus value */
+                       nxp,fspi-readsampleclksrc = <2>;
+               };
+       };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts
new file mode 100644 (file)
index 0000000..a715228
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               nxp-imx8mimage {
+                       args;   /* TODO: Needed by mkimage etype superclass */
+                       nxp,boot-from = "fspi";
+                       nxp,rom-version = <2>;
+                       nxp,loader-address = <0x10>;
+                       /* Bogus value */
+                       nxp,fspi-serialclkfreq = <9>;
+               };
+       };
+};
index 448d93d277a8a685e8026de05f8b45b7fd35a872..1545cf6e44c370f13ad347b84aa0c780d25dfbe9 100644 (file)
@@ -10,7 +10,6 @@
                nxp-imx8mimage {
                        args;   /* TODO: Needed by mkimage etype superclass */
                        nxp,boot-from = "fspi";
-                       /* Default nxp,fspi-header-filename = "fspi_header.bin"; */
                        nxp,rom-version = <2>;
                        nxp,loader-address = <0x10>;
                };