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 <[email protected]> --- doc/board/ti/j784s4_evm.rst | 267 ++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) diff --git a/doc/board/ti/j784s4_evm.rst b/doc/board/ti/j784s4_evm.rst index 22442874110..0c9dad122a7 100644 --- a/doc/board/ti/j784s4_evm.rst +++ b/doc/board/ti/j784s4_evm.rst @@ -280,6 +280,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 @@ -311,6 +315,269 @@ 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. + +Hardware Setup +^^^^^^^^^^^^^^ + +To boot J784S4 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. To enable +endpoint mode, build the boot loaders with the device tree overlay +``k3-j784s4-evm-pcie0-pcie1-ep.dtso``. + +PCIe Boot Procedure +^^^^^^^^^^^^^^^^^^^ + +The following steps describe how to boot J784S4 over PCIe: + +1. Compile the sample host program (provided below): + + .. prompt:: bash + + gcc -o pcie_boot_copy pcie_boot_copy.c + +2. Power on the J784S4-EVM (endpoint) after configuring boot mode switches. + +3. On the root complex, check PCIe enumeration: + + .. 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_copy j784s4 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: + + .. 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) + +6. Copy ``tispl.bin`` to the new BAR address (use ``lspci -vv`` to find): + + .. prompt:: bash + + sudo ./pcie_boot_copy j784s4 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_copy j784s4 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 boot 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 0x10000000 + + int main(int argc, char *argv[]) + { + char *bootfilename = NULL; + char *platform = NULL; + off_t bar1_address = 0; + int fd; + void *map_base; + int i = 0; + unsigned char *check; + int read_result; + long lSize; + int i; + FILE * fptr; + off_t load_addr, load_addr_offset, start_addr_offset; + unsigned int magic_word = 0; + int use_magic_word = 0; + + if (argc != 4) { + printf("Usage: %s <platform> <bar_address> <binary_file>\n", argv[0]); + printf(" platform: am64x or j784s4\n"); + return 0; + } + + platform = argv[1]; + bar1_address = strtoul(argv[2], NULL, 16); + bootfilename = argv[3]; + + printf("platform: %s\n", platform); + printf("bootfilename: %s\n", bootfilename); + printf("bar1_address: 0x%lx\n", bar1_address); + + if(!strcmp(bootfilename,"tiboot3.bin")) + { + if(!strcmp(platform, "j784s4")) + { + load_addr = 0x41C00000; + load_addr_offset = 0x00; + start_addr_offset = 0xf3fe0; + magic_word = 0xB17CEAD9; + use_magic_word = 1; + } + else + { + printf("Unsupported platform: %s\n", platform); + return 0; + } + } + else + { + load_addr = 0x0; + load_addr_offset = 0x0; + start_addr_offset = MAP_SIZE - 0x4; + } + + printf("load_addr: 0x%lx\n", load_addr); + printf("load_addr_offset: 0x%lx\n", load_addr_offset); + printf("start_addr_offset: 0x%lx\n", start_addr_offset); + if (use_magic_word) + printf("magic_word: 0x%x\n", magic_word); + + printf("try to open /dev/mem.\n"); + fd = open("/dev/mem", O_RDWR | O_SYNC); + if(fd == -1) + { + printf("failed to open /dev/mem.\n"); + return -1; + } + + map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, bar1_address); + if(map_base == (void *)-1) + { + printf("can't mmap.\n"); + return -1; + } + printf("mmap done\n"); + + fptr = fopen(bootfilename, "rb"); + if (fptr == NULL) { + printf("can't read bootfile.\n"); + return -1; + } + + fseek(fptr, 0, SEEK_END); + lSize = ftell(fptr); + rewind(fptr); + + printf("bootfile size = 0x%lx\n", lSize); + + check = (unsigned char *)malloc(sizeof(char) * lSize); + if(check == NULL) + { + printf("malloc failed\n"); + return -1; + } + + read_result = fread(check, 1, lSize, fptr); + if(read_result != lSize) + { + printf("fread failed\n"); + return -1; + } + + for(i = 0; i < lSize; i++) + { + *((char *)(map_base) + load_addr_offset + i) = check[i]; + } + printf("Image copy done.\n"); + + sleep(1); + + *(unsigned int *)(map_base + start_addr_offset) = (unsigned int)(load_addr_offset + load_addr); + + // Write magic word for J784S4 at R5 stage + if(use_magic_word) + { + *(unsigned int *)(map_base + start_addr_offset + 4) = magic_word; + printf("Magic word written.\n"); + } + + 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.34.1

