Device Tree

Building Device Tree for the board that you are using.

Prerequisites

This section assumes that the following prerequisites have been satisfied:

  • Xilinx SDK installed.

  • git installed.

VSI applications running on ARM require a Linux Device Tree entry for the FPGA driver. There are different techniques that can be used to achieve this. In the sections that follow, two use cases are discussed. The first involves updating the Device Tree of an already existing Linux build, the second involves using PetaLinux build tools with a custom Device Tree specification. Either method will involve first determining what the definition of the device node is; and for this, the developer must first ascertain if the processor on their board is 32-bit or 64-bit. The structure of the device node entries will be like one of the following skeleton entries (where TBD represents interrupt values that will be determined in later steps):

  • 32-bit (such as XC7Z020 / Zynq-7000):

vsi_driver_plat@80000000 {
	compatible = "xlnx,sv_driver_plat";
	interrupt-parent = <TBD>;
	interrupts = <TBD>;
	reg = <0x80000000 0x000fffff 0x88000000 0x000fffff>;
};
  • 64-bit (such as XCZU9EG / MPSoC):

vsi_driver_plat@80000000 {
	compatible = "xlnx,sv_driver_plat";
	interrupt-parent = <TBD>;
	interrupts = <TBD>;
	reg = <0x0 0x80000000 0x0 0x000C000 0x0 0x88000000 0x0 0x08000000>;
};
  1. Create a new text file, and copy one of the two skeleton entries (whichever corresponds to the target CPU architecture).

  2. To ascertain the correct interrupt values, the VSI project must first be fully built, and from there the values can be extracted from the HDF file using the Xilinx SDK hsi utility. In the VSI project, the file should be located under the directory vsi_auto_gen/.platform. For example, with a zynq platform it’s at:

    <VSI-project-path>/vsi_auto_gen/.platform/zynq_platform/zynq_pl.hdf
    
  3. Now, create a working directory such as “dtWork”, cd into it and clone Xilinx’s device tree sources in it:

    $ git clone https://github.com/Xilinx/device-tree-xlnx
    
  4. Then copy the HDF file into it and launch hsi:

    $ cp <VSI-project-path>/vsi_auto_gen/.platform/zynq_platform/zynq_pl.hdf ./
    $ hsi
    
  5. Inside hsi, use the following commands to extract the device tree data:

    hsi% open_hw_design ./zynq_pl.hdf
    hsi% set_repo_path ./device-tree-xlnx/
    

    (proc note for following command: for ZynqMP psu_cortexa53_0, for Zynq ps7_cortexa9_0, for Microblaze microblaze_0)

    hsi% create_sw_design device-tree -os device_tree -proc ps7_cortexa9_0
    hsi% generate_target -dir my_dts
    hsi% exit
    
  6. This will create a subdirectory called my_dts, and inside it a file called pl.dtsi that has the required values for the field “interrupts”. Open this file in a text editor and do a search for the string “@80000000”. Under the device node that this search locates, the “interrupts” values can be found. Now go back to the text file in which the skeleton device node entry was placed, and fill in the TBD interrupts values, with those just ascertained from the pl.dtsi file. For example, if the target IC is a 32-bit XC7Z020 Zynq-7000 (found on a ZedBoard), using a pl.dtsi file generated from the Getting Started example application, this looks like:

    vsi_driver_plat@80000000 {
    	compatible = "xlnx,sv_driver_plat";
    	interrupt-parent = <TBD>;
    	interrupts = <0 29 4>;
    	reg = <0x80000000 0x000fffff 0x88000000 0x000fffff>;
    };
    
  7. At this point, it must be decided which method will be used to insert this device into the Linux Device Tree for the target board:

Case 1: Updating Existing Linux Build

Case 2: Insertion Using Petalinux Tools

Case 1: Updating Existing Linux Build

Prerequisites

This section assumes that the following prerequisites have been satisfied:

  • A build of Linux for target board that allows switching out device tree file (*.DTB).

  • DTC (device tree compiler) utility for DTB/DTS conversion. (try: sudo apt-get install device-tree-compiler)

Updating Linux Flow

  1. In this scenario, there should be a device tree blob (.DTB) file on the boot partion of the existing Linux build. In the develpment environment, create a working directory, such as “DTCWork”, and copy this file into it. Rename the file with a remark to indicate it’s the original version. For example, if the file is called system.dtb, rename it to system-orig.dtb.

  2. Now inside the working directory, issue the following command to convert the dtb to a text based dts file:

    $ dtc -I dtb -O dts -o system.dts system-orig.dtb
    
  3. Open the newly created system.dts file in a text editor, and run a search for the string “amba” as this is the device branch which from which the “interrupt-parent” value will be copied. Take the value for interrupt parent under the amba section, and and fill it into the corresponding TBD field in the skeleton node. For example, in the follow screen shot, the value to be copied is 0x4:../_images/find_interrupt_parent.pngpic

  4. Now in system.dts, search for the string “amba_pl”, as this is the branch under which the driver node entry should be placed. For example, if this search finds the amba_pl device branch as follows:../_images/find_amba_pl.pngpic

  5. Insert the newly created vsi_driver_plat from the steps above as follows:../_images/inserted_node.pngpic

  6. Save the DTS file, then issue the following command to convert it back to DTB format:

    $ dtc -I dts -O dtb -o system.dtb system.dts
    
  7. Then take this .dtb file and overwrite in on top of the version that’s on the target board’s boot partition to complete the process for this use case.

Case 2: Insertion Using Petalinux Tools

The steps that follow assume that the target board has a 64-bit processor (eg zcu102), and that the interrupts values discovered from the pl.dtsi in the first section was <0x0 0x59 0x4>. So if following for a 32-bit CPU, use the node entry format for that architecture instead.

Prerequisites

This section assumes that the following prerequisites have been satisfied:

  • PetaLinux Tools is installed.

  • PetaLinux Working Environment is setup.

Petalinux Flow

BSP package was used to built the petalinux project. However users, can also use the HDF exported from Vivado to build the project. (BSP can be downloaded from the Xilinx website here.)

  1. Change to the directory under which you want PetaLinux projects to be created.

  2. Run petalinux-create command on the command console:

    petalinux-create -t project -s <path-to-bsp>
    
  3. Modify the system-user.dtsi file in the following path:

    <petalinux-project-path>/project-spec/meta-user/recipes-bsp/device-tree/files/
    

    to have the VSI driver node. Example using 64-bit zcu102 board; replace with 32-bit node entry if necessary.

    /include/ "system-conf.dtsi"
    /{
    	amba {
    		vsi_driver_plat@80000000 {
    			compatible = "xlnx,sv_driver_plat";
    			interrupt-parent = <0x4>;
    			interrupts = <0x0 0x59 0x4>;  
    			reg = <0x0 0x80000000 0x0 0x000C000 0x0 0x88000000 0x0 0x08000000>;
    		};
    	};
    };
    

    The interrupt number in this example is the default interrupt number when you connect to interrupt number zero. To determine your definite interrupt values from the VSI project HDF, see the first section of this page.

  4. Configure Petalinux:

    petalinux-config
    
     - Subsystem auto hardware -> advanced bootable images storage settings -> dtb image settings ->IMAGE STORAGE MEDIA -> primary sd
     - Image Packaging Configuration -> Root FS type -> sd card
     - Image Packaging Configuration -> Turn off copy final image to tftp boot
     - yocto settings -> disable network sstate feeds
    
  5. Build the Device Tree:

    petalinux-build -c device-tree
    

    This will create the image/linux directory.

  6. Use the files in pre_built directory to create the BOOT.BIN as follow:

    petalinux-package --boot --fsbl zynqmp_fsbl.elf --fpga system.bit --pmufw pmufw.elf --u-boot
    

Copy image.ub and BOOT.BIN from image/linux to your SD card.