[PATCH v5 10/10] docs: board: ti: j784s4_evm: Add PCIe boot documentation

Siddharth Vadapalli s-vadapalli at ti.com
Mon Feb 16 11:28:38 CET 2026


From: Hrushikesh Salunke <h-salunke at ti.com>

Add PCIe boot documentation for J784S4-EVM including boot mode switch
settings, hardware setup requirements, endpoint configuration details
and step-by-step boot procedure.

Signed-off-by: Hrushikesh Salunke <h-salunke at ti.com>
[s-vadapalli at ti.com: simplified and documented the pcie_boot_util program]
Co-developed-by: Siddharth Vadapalli <s-vadapalli at ti.com>
Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
---
 doc/board/ti/j784s4_evm.rst | 305 ++++++++++++++++++++++++++++++++++++
 1 file changed, 305 insertions(+)

diff --git a/doc/board/ti/j784s4_evm.rst b/doc/board/ti/j784s4_evm.rst
index d858dc7cdbb..fb767bedbf6 100644
--- a/doc/board/ti/j784s4_evm.rst
+++ b/doc/board/ti/j784s4_evm.rst
@@ -299,6 +299,10 @@ http://www.ti.com/lit/zip/spruj52 under the `Boot Mode Pins` section.
      - 00000000
      - 01110000
 
+   * - PCIe
+     - 10001000
+     - 01010000
+
 For SW7 and SW11, the switch state in the "ON" position = 1.
 
 Boot Mode Pins for AM69-SK
@@ -330,6 +334,307 @@ section.
 
 For SW2, the switch state in the "ON" position = 1.
 
+PCIe Boot
+---------
+
+The J784S4 SoC supports booting over PCIe, allowing the device to function
+as a PCIe endpoint and receive boot loader images from a PCIe Root Complex.
+The PCIe1 instance of PCIe is configured by Boot ROM for Endpoint Mode of
+operation. Hence, the PCIe Connector on the EVM corresponding to PCIe1
+should be utilized for PCIe Boot.
+
+Hardware Setup
+^^^^^^^^^^^^^^
+
+To boot the J784S4 EVM via PCIe, the following hardware setup is required:
+
+1. Configure the boot mode switches on J784S4-EVM for PCIe boot:
+
+   .. code-block:: text
+
+      SW7:  01010000
+      SW11: 10001000
+
+2. Connect the J784S4-EVM (endpoint) to a PCIe Root Complex (e.g., x86 host)
+   using a PCIe cable. Both boards should be powered off before making the
+   connection.
+
+Endpoint Configuration
+^^^^^^^^^^^^^^^^^^^^^^
+
+The following configuration options are enabled by default in
+``j784s4_evm_r5_defconfig`` and ``j784s4_evm_a72_defconfig``:
+
+- ``CONFIG_SPL_PCI_DFU_BAR_SIZE``: Size of the PCIe BAR for DFU/boot image download
+- ``CONFIG_SPL_PCI_DFU_VENDOR_ID``: PCIe vendor ID advertised by the endpoint
+- ``CONFIG_SPL_PCI_DFU_DEVICE_ID``: PCIe device ID advertised by the endpoint
+- ``CONFIG_SPL_PCI_DFU_MAGIC_WORD``: Magic word written by Root Complex to signal image transfer completion
+- ``CONFIG_SPL_PCI_DFU_BOOT_PHASE``: Current boot phase indicator for Root Complex
+
+By default, PCIe Root Complex mode is enabled in the device tree. For PCIe Boot,
+build the Bootloaders with the following content added to k3-j784s4-evm-u-boot.dtsi:
+
+.. code-block:: devicetree
+
+   &serdes0 {
+           /delete-property/ serdes0_usb_link;
+   };
+
+   &serdes_refclk {
+           bootph-all;
+   };
+
+   &serdes0_pcie1_link {
+           bootph-all;
+   };
+
+   &serdes_ln_ctrl {
+           bootph-all;
+   };
+
+   &pcie1_ctrl {
+           bootph-all;
+   };
+
+   &pcie1_rc {
+           status = "disabled";
+   };
+
+   &cbass_main {
+           pcie1_ep: pcie-ep at 2910000 {
+                   compatible = "ti,j784s4-pcie-ep";
+                   reg = <0x00 0x02910000 0x00 0x1000>,
+                         <0x00 0x02917000 0x00 0x400>,
+                         <0x00 0x0d800000 0x00 0x00800000>,
+                         <0x00 0x18000000 0x00 0x08000000>;
+                   reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+                   interrupt-names = "link_state";
+                   interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+                   ti,syscon-pcie-ctrl = <&pcie1_ctrl 0x0>;
+                   max-link-speed = <3>;
+                   num-lanes = <2>;
+                   power-domains = <&k3_pds 333 TI_SCI_PD_EXCLUSIVE>;
+                   clocks = <&k3_clks 333 0>;
+                   clock-names = "fck";
+                   max-functions = /bits/ 8 <6>;
+                   max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
+                   dma-coherent;
+                   phys = <&serdes0_pcie1_link>;
+                   phy-names = "pcie-phy";
+                   bootph-all;
+           };
+   };
+
+PCIe Boot Procedure
+^^^^^^^^^^^^^^^^^^^
+
+The following steps describe the process of booting J784S4-EVM over PCIe:
+
+1. Compile the sample host program (provided after this section):
+
+   .. prompt:: bash
+
+      gcc -o pcie_boot_util pcie_boot_util.c
+
+2. Power on the J784S4-EVM (endpoint) after configuring boot mode switches
+   for PCIe Boot.
+
+3. Copy the compiled sample host program (pcie_boot_util) and the bootloader
+   images to the Root Complex. Check PCIe enumeration on Root Complex to ensure
+   that the J784S4 EVM shows up as the PCIe Endpoint:
+
+   .. prompt:: bash
+
+      lspci
+
+   The endpoint will appear as a RAM device or with multiple functions:
+
+   .. code-block:: text
+
+      0000:00:00.0 PCI bridge: Texas Instruments Device b012
+      0000:01:00.0 RAM memory: Texas Instruments Device b012
+      0000:01:00.1 Non-VGA unclassified device: Texas Instruments Device 0100
+      0000:01:00.2 Non-VGA unclassified device: Texas Instruments Device 0100
+
+4. Copy ``tiboot3.bin`` to the endpoint. Use ``lspci -vv`` to identify the BAR
+   address:
+
+   .. prompt:: bash
+
+      sudo ./pcie_boot_util 0x4007100000 tiboot3.bin
+
+   The sample program automatically writes the image start address to
+   ``0x41CF3FE0`` and the magic word ``0xB17CEAD9`` to ``0x41CF3FE4``.
+
+5. After ``tiboot3.bin`` is processed, the PCIe link will go down briefly.
+   Remove the PCIe device and rescan the bus:
+
+   .. prompt:: bash
+
+      echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/remove
+      echo 1 > /sys/bus/pci/devices/0000\:00\:00.0/rescan
+      lspci
+
+   The enumeration will change to something similar:
+
+   .. code-block:: text
+
+      0000:00:00.0 PCI bridge: Texas Instruments Device b012
+      0000:01:00.0 RAM memory: Texas Instruments Device b010 (rev dc)
+
+   .. note::
+
+      When the Root-Complex enumerates the PCIe Endpoint after a 'remove-rescan' sequence,
+      it is possible that the 'BAR' appears 'disabled'. If so, writing to the BAR via the
+      'pcie_boot_util' to transfer the bootloader image will have no effect. In such cases,
+      run 'setpci -s 0000:01:00.0 COMMAND=0x02' on the Root-Complex after enumeration
+      (with appropriate DOMAIN:BUS:DEVICE.FUNCTION corresponding to the Endpoint) to enable
+      the BAR.
+
+6. Copy ``tispl.bin`` to the new BAR address (use ``lspci -vv`` to find):
+
+   .. prompt:: bash
+
+      sudo ./pcie_boot_util 0x4000400000 tispl.bin
+
+7. After ``tispl.bin`` is processed, the PCIe link will go down again. Remove
+   and rescan the PCIe device:
+
+   .. prompt:: bash
+
+      echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/remove
+      echo 1 > /sys/bus/pci/devices/0000\:00\:00.0/rescan
+
+8. Copy ``u-boot.img``:
+
+   .. prompt:: bash
+
+      sudo ./pcie_boot_util 0x4000400000 u-boot.img
+
+9. After ``u-boot.img`` is successfully loaded, the boot process is complete
+   and endpoint should boot till U-Boot prompt.
+
+.. note::
+
+   During the boot process, "PCIe LINK DOWN" messages might appear in kernel
+   logs. This is expected as the endpoint resets and re-initializes the PCIe
+   link after processing each boot stage.
+
+Sample Host Program
+^^^^^^^^^^^^^^^^^^^
+
+The following C program can be used on the Root Complex to copy bootloader images
+to the J784S4 endpoint:
+
+.. code-block:: c
+
+   #include <stdio.h>
+   #include <stdlib.h>
+   #include <fcntl.h>
+   #include <sys/mman.h>
+   #include <unistd.h>
+   #include <string.h>
+
+   #define MAP_SIZE 0x400000
+
+   /*
+    * bootloader_file: Path to the bootloader image (tiboot3.bin, tispl.bin and u-boot.img)
+    * bootloader_mem: Memory allocated in RAM for reading the bootloader image file
+    * bar_address: Address of BAR to which bootloader image will be written
+    * bar_map_base: Mapping of the BAR Base Address for the program
+    * load_address: Address in BAR region where bootloader is being transferred
+    * transfer_completion_offset: Offset in BAR region to write to notify completion of transfer
+    * fd_mem: File descriptor for opening /dev/mem
+    * fptr: File pointer for bootloader image in filesystem
+    * magic_word: Magic word to notify completion of tiboot3.bin transfer to Boot ROM
+    * use_magic_word: Flag to indicate if Magic Word has to be written
+    * file_size: Size of bootloader image
+    * i: Iterator used during bootloader image transfer
+    */
+   int main(int argc, char *argv[])
+   {
+      off_t bar_address, load_address, transfer_completion_offset;
+      unsigned char *bootloader_mem;
+      const char *bootloader_file;
+      int fd_mem, i, use_magic_word;
+      unsigned int magic_word;
+      void *bar_map_base;
+      long file_size;
+      FILE * fptr;
+
+      if (argc != 3) {
+          printf("Usage: %s <bar_address> <bootloader_file>\n", argv[0]);
+          return 0;
+      }
+
+      bar_address = strtoul(argv[1], NULL, 16);
+      bootloader_file = argv[2];
+
+      printf("Bootloader File: %s\n", bootloader_file);
+      printf("BAR Address: 0x%lx\n", bar_address);
+
+      if(!strcmp(bootloader_file,"tiboot3.bin")) {
+          transfer_completion_offset = 0xF3FE0;
+          load_address = 0x41C00000;
+          magic_word = 0xB17CEAD9;
+          use_magic_word = 1;
+      } else {
+          transfer_completion_offset = MAP_SIZE - 0x4;
+          load_address = 0xDEADBEEF;
+          use_magic_word = 0;
+      }
+
+      fd_mem = open("/dev/mem", O_RDWR | O_SYNC);
+      if(fd_mem == -1) {
+          printf("failed to open /dev/mem\n");
+          return -1;
+      }
+
+      bar_map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd_mem, bar_address);
+      if(bar_map_base == (void *)-1) {
+          printf("failed to map BAR\n");
+          return -1;
+      }
+
+      fptr = fopen(bootloader_file, "rb");
+      if (!fptr) {
+          printf("failed to read bootloader file\n");
+          return -1;
+      }
+
+      fseek(fptr, 0, SEEK_END);
+      file_size = ftell(fptr);
+      rewind(fptr);
+
+      bootloader_mem = (unsigned char *)malloc(sizeof(char) * file_size);
+      if(!bootloader_mem) {
+         printf("failed to allocate local memory for bootloader file\n");
+         return -1;
+      }
+
+      if (fread(bootloader_mem, 1, file_size, fptr) != file_size) {
+          printf("failed to read bootloader file into local memory\n");
+          return -1;
+      }
+
+      for(i = 0; i < file_size; i++) {
+          *((char *)(bar_map_base) + i) = bootloader_mem[i];
+      }
+
+      *(unsigned int *)(bar_map_base + transfer_completion_offset) = (unsigned int)(load_address);
+
+      if(use_magic_word) {
+          *(unsigned int *)(bar_map_base + transfer_completion_offset + 4) = magic_word;
+          printf("Magic word written for Boot ROM\n");
+      }
+
+      printf("Transferred %s to Endpoint\n", bootloader_file);
+      return 0;
+   }
+
+This program copies the boot image to the PCIe endpoint's memory region and
+writes the necessary control words to signal image transfer completion.
+
 Debugging U-Boot
 ----------------
 
-- 
2.51.1



More information about the U-Boot mailing list