Introduction
The ZynqMp Programmable Logic (PL) can be programmed either using First Stage Boot-loader (FSBL), U-Boot or through Linux.
This page is provide the details about programming the PL from Linux world.

Software Flow


flow.PNG
XilFPGA library acts as a bridge between the Linux application and the PL device. It provides the required functionality to the user application for programming the PL device with the required bitstream.

References:
https://github.com/Xilinx/embeddedsw/tree/master/lib/sw_services/xilfpga/doc
https://github.com/Xilinx/linux-xlnx/blob/master/Documentation/fpga/fpga-mgr.txt
https://github.com/Xilinx/linux-xlnx/blob/master/Documentation/devicetree/bindings/fpga/fpga-region.txt

HW IP Features

  • Full-Bitstream and partial Bitstream loading.
  • Encrypted and Authenticated Bitstream loading.

Features supported in the driver

  • Full-Bitstream Bitstream loading.
  • Partial Reconfiguration (Partial bitstream loading).
  • Encrypted Bitstream loading with user key.
  • Authenticated Bitstream loading.
  • Authenticated and Encrypted Bitstream loading.

Missing Features, Known Issues and Limitations in the driver

  • The driver does not work as a module.
  • It is capable of loading only .bin format files into PL. It does not support any other file format.
  • No support for PS-PL configuration.
  • No support for Partial Reconfiguration in DTG (No support for Partial Bitstream loading with Device Tree Overlay).
  • No out-of-box automated solution for creating Device Tree Overlays with Xilinx Petalinux flow
  • No support for Read-back Bitstream.

NOTE:
The descriptions in subsequent sections refer to use of Device Tree Overlay (DTO) fragments with FPGA manager framework. It has to be noted that the generation of DTO fragments are not supported in official Xilinx 2018.2 and earlier release of Petalinux. This support is under development and will be available in later releases of Petalinux.
Sections below describe steps for manual creation of pl.dtsi (contains the DTO fragment) to be used along with Xilinx 2018.2 Linux.

Kernel Configuration

The following config options should be enabled in order to use FPGA Manager (In zynqmp_defconfig this options are enabled by default)

ZynqMP FPGA Manager Configuration:
Select: Device Drivers ---> FPGA Configuration Framework
config1.png

DT overlay ConfigFS interface Configuration:
This is required only if the user is using to the Bistream using DTO
Select: Device Drivers --> Device Tree and Open Firmware support

config2.png
Contiguous Memory Allocator Configuration:
Contiguous Memory Allocator which allows drivers to allocate big physically-contiguous blocks of memory which is needed for Bitstream programming.
CONFIG_CMA=y
CONFIG_DMA_CMA=y

Device-tree

pcap {
       compatible = "xlnx,zynqmp-pcap-fpga";
};
fpga_full: fpga-full {
       compatible = "fpga-region";
       fpga-mgr = <&pcap>;
       #address-cells = <2>;
       #size-cells = <2>;
};
Reference Link for device-tree bindings:
https://github.com/Xilinx/linux-xlnx/blob/master/Documentation/devicetree/bindings/fpga/fpga-region.txt

FPGA programming using Device Tree Overlay (DTO)

The Device Tree Overlay (DTO) is used to reprogram an FPGA while Linux is running. The DTO overlay will add the child node and the fragments from the .dtbo file to the base device tree,, The newly added device node/drivers will be probed after bitstream programming

DTO contains:
  • Target FPGA Region
    - "target-path" or "target" - The insertion point where the the contents of the overlay will go into the live tree.
    target-path is a full path, while target is a phandle.

  • FPGA Image firmware file name
    - "firmware-name" - Specifies the name of the FPGA image file on the firmware search path.
    The search path is described in the firmware class documentation.

  • Image specific information
    - external-fpga-config : boolean, set if the FPGA has already been configured prior to Linux boot up.

  • Child devices
    - child nodes corresponding to hardware that will be loaded in this region of the FPGA.

Steps for programming the bitstream using overlay: Refer

Steps to remove the drivers got added as part of DTO: Refer

Example:
//Device Tree Example: Full Reconfiguration without Bridges
// HSI Generated overlay/pl.dtsi file.
// Enable the axi-gpio interface
/dts-v1/;
/plugin/;
 
/ {
 
    fragment@0 {
 
        target = <&fpga_full>;
        #address-cells = <1>;
        #size-cells = <1>;
 
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <1>;
 
            firmware-name = "design_1_wrapper.bit.bin";
        };
    };
 
    fragment@1 {
 
                target = <&amba>;
                __overlay__ {
                        axi_gpio_0: gpio@a0000000 {
                                #gpio-cells = <2>;
                                compatible = "xlnx,xps-gpio-1.00.a";
                                gpio-controller ;
                                reg = <0x0 0xa0000000 0x0 0x10000>;
                                xlnx,all-inputs = <0x0>;
                                xlnx,all-inputs-2 = <0x0>;
                                xlnx,all-outputs = <0x1>;
                                xlnx,all-outputs-2 = <0x0>;
                                xlnx,dout-default = <0x00000000>;
                                xlnx,dout-default-2 = <0x00000000>;
                                xlnx,gpio-width = <0x8>;
                                xlnx,gpio2-width = <0x20>;
                                xlnx,interrupt-present = <0x0>;
                                xlnx,is-dual = <0x0>;
                                xlnx,tri-default = <0xFFFFFFFF>;
                                xlnx,tri-default-2 = <0xFFFFFFFF>;
                        };
                };
        };
 
};

Tools Required

NOTE:
  • To support device-tree overlay the DTC compiler version should be >= 1.4.4

Images Required for testing

  • FSBL
  • PMUFW
  • ATF
  • u-boot
  • Linux Image (image)
    Refer below link to build the above images:
    http://www.wiki.xilinx.com/ZCU102+Image+creation+in+OSL+flow
  • Device-tree (system.dtb)
    Refer below link to build device-tree
    http://www.wiki.xilinx.com/ZCU102+Image+creation+in+OSL+flow#Build%20device-tree
    Device-tree Compilation with DT-Overlay
    A utility called device tree compiler (DTC) is used to compile the DTS file into a DTB file. DTC is part of the Linux source directory. linux-xlnx/scripts/dtc/ contains the source code for DTC and needs to be compiled in order to be used.
    • $ ./scripts/dtc/dtc -O dtb -o my_dts/system-top.dtb -b 0 -@ my_dts/system-top.dts
      Note: To support the device-tree overlay the base tree should be compile with -@ flags to generate the symbols.
  • Bin file
  • DTBO file

Generating .bin from .bit file using Bootgen

bootgen -image Bitstream.bif -arch zynqmp -o ./Bitstream.bin -w
Note: For 2017.4 and earlier releases use the below command to generate the .bin from .bit file using Bootgen
bootgen -image Bitstream.bif -arch zynqmp -process_bitstream bin

Bitstream.bif file should contains the below lines:
all:
{
        Full.bit (or)  Partial.bit /* Bitstream file name */
}
Required Steps to Create the DT-Overlay Fragment for the Given HDF
  1. Clone the device-tree-xlnx repo:
    git clone https://github.com/Xilinx/device-tree-xlnx.git
  2. Helper script:

  • Command: xsct dt_overaly.tcl system.hdf psu_cortexa53_0 device-tree-xlnx output_dir
  • Example: xsct dt_overaly.tcl system.hdf psu_cortexa53_0 ${DTS_REPO}/device-tree-xlnx overlay

The command will create the overlay file with the required DT-Overlay fragments (overlay/pl.dtsi)
// HSI Generated overlay/pl.dtsi file.
// Enable the axi-gpio interface
/dts-v1/;
/plugin/;
 
/ {
 
    fragment@0 {
 
        target = <&fpga_full>;
        #address-cells = <1>;
        #size-cells = <1>;
 
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <1>;
 
            firmware-name = "design_1_wrapper.bit.bin";
        };
    };
 
    fragment@1 {
 
                target = <&amba>;
                __overlay__ {
                        axi_gpio_0: gpio@a0000000 {
                                #gpio-cells = <2>;
                                compatible = "xlnx,xps-gpio-1.00.a";
                                gpio-controller ;
                                reg = <0x0 0xa0000000 0x0 0x10000>;
                                xlnx,all-inputs = <0x0>;
                                xlnx,all-inputs-2 = <0x0>;
                                xlnx,all-outputs = <0x1>;
                                xlnx,all-outputs-2 = <0x0>;
                                xlnx,dout-default = <0x00000000>;
                                xlnx,dout-default-2 = <0x00000000>;
                                xlnx,gpio-width = <0x8>;
                                xlnx,gpio2-width = <0x20>;
                                xlnx,interrupt-present = <0x0>;
                                xlnx,is-dual = <0x0>;
                                xlnx,tri-default = <0xFFFFFFFF>;
                                xlnx,tri-default-2 = <0xFFFFFFFF>;
                        };
                };
        };
 
};
Compiling a Device Tree Overlay Blob (.dtbo) file from the pl.dts file.
dtc -O dtb -o pl.dtbo -b 0 -@ pl.dtsi
Example: ./scripts/dtc/dtc -O dtb -o pl.dtbo -b 0 -@ pl.dtsi
For more info about DTG please refer the below link
http://www.wiki.xilinx.com/Build%20Device%20Tree%20Blob

Test Procedure

Full Bitstream Using Device Tree Overlay:

Steps to Load Full Bitstream
Once the Linux is up run the below commands to load the required Full Bitstream.
1) Set flags for Full Bitstream.
  • echo 0 > /sys/class/fpga_manager/fpga0/flags

2) Copy the Full BitStream (.bin) and pl.dtbo files into firmware folder
  • mount /dev/mmcblk0p1 /media/
  • mkdir -p /lib/firmware
  • cp /media/full.bin /lib/firmware/design_1_wrapper.bit.bin
  • cp /media/pl.dtbo /lib/firmware/

3) Apply DTBO (To add device nodes)
  • mkdir /configfs
  • mount -t configfs configfs /configfs
  • cd /configfs/device-tree/overlays/
  • mkdir full
  • echo -n "pl.dtbo" > full/path

4) Steps to remove device nodes
  • rmdir full

Steps to Re-Load Full Bitstream
1) Remove The overlay file will be applied earlier.
  • rmdir full
2) Set flags for Full BitStream.
  • echo 0 > /sys/class/fpga_manager/fpga0/flags

3) Copy the Full BitStream and pl.dtbo files into firmware folder
  • cp /media/full1.bin /lib/firmware/design_1_wrapper.bit.bin
  • cp /media/new-pl.dtbo /lib/firmware/
3) Apply DTBO
  • mkdir full
  • echo -n "new-pl.dtbo" > full/path

Full Bitstream Expected Output Using DTBO

root@plnx_aarch64:~# mount /dev/mmcblk0 /media/root@plnx_aarch64:~# cp /media/design_1_wrapper.bit.bin /lib/firmware/design_1_wrapper.bit.bin
root@plnx_aarch64:~# cp /media/pl.dtbo /lib/firmware/
root@plnx_aarch64:~# mkdir /configfs
root@plnx_aarch64:~# mount -t configfs configfs /configfs
root@plnx_aarch64:~# cd /configfs/device-tree/overlays/
root@plnx_aarch64:/configfs/device-tree/overlays# mkdir full
root@plnx_aarch64:/configfs/device-tree/overlays# echo -n "pl.dtbo" > full/path
[   53.605514] fpga_manager fpga0: writing design_1_wrapper.bit.bin to Xilinx ZynqMP FPGA Manager
[   53.998175] GPIO IRQ not connected
[   54.001551] XGpio: /amba/gpio@a0000000: registered, base is 298
root@plnx_aarch64:/configfs/device-tree/overlays# cat /sys/class/gpio/gpiochip298/label
/amba/gpio@a0000000
root@plnx_aarch64:/configfs/device-tree/overlays# echo 299 > /sys/class/gpio/export
root@plnx_aarch64:/configfs/device-tree/overlays# echo out > /sys/class/gpio/gpio299/direction
root@plnx_aarch64:/configfs/device-tree/overlays# echo 1 > /sys/class/gpio/gpio299/value
root@plnx_aarch64:/configfs/device-tree/overlays# echo 0 > /sys/class/gpio/gpio299/value
root@plnx_aarch64:/configfs/device-tree/overlays# ls /sys/firmware/devicetree/base/amba/
#address-cells              dma@fd4c0000                dma@ffa90000                dp_snd_pcm0                 i2c@ff020000                ranges                      timer@ff110000
#size-cells                 dma@fd500000                dma@ffaa0000                dp_snd_pcm1                 i2c@ff030000                rtc@ffa60000                timer@ff120000
PERIPHERAL@ff380000         dma@fd510000                dma@ffab0000                dp_sub@fd4aa000             linux,phandle               sdhci@ff160000              timer@ff130000
PERIPHERAL@ff990000         dma@fd520000                dma@ffac0000                ethernet@ff0b0000           memory-controller@fd070000  sdhci@ff170000              timer@ff140000
ahci@fd0c0000               dma@fd530000                dma@ffad0000                ethernet@ff0c0000           memory-controller@ff960000  serial@ff000000             u-boot,dm-pre-reloc
ams@ffa50000                dma@fd540000                dma@ffae0000                ethernet@ff0d0000           name                        serial@ff010000             usb0
can@ff060000                dma@fd550000                dma@ffaf0000                ethernet@ff0e0000           nand@ff100000               smmu@fd800000               usb1
can@ff070000                dma@fd560000                dp@fd4a0000                 gpio@a0000000               pcie@fd0e0000               spi@ff040000                watchdog@fd4d0000
cci@fd6e0000                dma@fd570000                dp_snd_card                 gpio@ff0a0000               phandle                     spi@ff050000                xilinx_drm
compatible                  dma@ffa80000                dp_snd_codec0               gpu@fd4b0000                pinctrl@ff180000            spi@ff0f0000                zynqmp_phy@fd400000

Full Bitstream Using sysfs interface

Once the linux is up run the below commands to load the Bitstream.
1)Set flags for Full Bitstream.
  • echo 0 > /sys/class/fpga_manager/fpga0/flags

2) Loading BitStream into PL.
  • mkdir -p /lib/firmware
  • cp /media/design_1_wrapper.bit.bin /lib/firmware/
  • echo design_1_wrapper.bit.bin > /sys/class/fpga_manager/fpga0/firmware

Full Bitstream Expected Output Using Sysfs

root@Xilinx:~# mount /dev/mmcblk0p1 /media/
root@Xilinx:~#mkdir -p /lib/firmware
root@Xilinx:~# echo 0 > /sys/class/fpga_manager/fpga0/flags
root@Xilinx:~# cp /media/system_wrapper.bit.bin /lib/firmware/
root@Xilinx:~# echo system_wrapper.bit.bin > /sys/class/fpga_manager/fpga0/firmware
[  120.266851] fpga_manager fpga0: writing system_wrapper.bit.bin to Xilinx Zynqmp FPGA Manager
root@Xilinx:~# devmem 0xA0000000
0x00000000

Partial Bitstream Using sysfs interface

once the Linux is up run the below commands to load the required Partial Bitstream.
1) Set flags for Partial Bitstream.
  • echo 1 > /sys/class/fpga_manager/fpga0/flags
2) Loading Bitstream into PL.
  • mkdir -p /lib/firmware
  • cp /media/partial.bin /lib/firmware/
  • echo partial.bin > /sys/class/fpga_manager/fpga0/firmware

Partial Bitstream Expected Output Using Sysfs

xilinx-zcu102-2018_2 login: root
Password:
root@xilinx-zcu102-2018_2:~# mount /dev/mmcblk0p1 /media/
root@xilinx-zcu102-2018_2:~# cp /media/full.bin /lib/firmware/
root@xilinx-zcu102-2018_2:~# cp /media/On.bin /lib/firmware/
root@xilinx-zcu102-2018_2:~# cp /media/off.bin /lib/firmware/
root@xilinx-zcu102-2018_2:~# echo full.bin > /sys/class/fpga_manager/fpga0/firmware
[   95.636462] fpga_manager fpga0: writing full.bin to Xilinx ZynqMP FPGA Manager
root@xilinx-zcu102-2018_2:~# devmem 0x80000000
0x000000AA
root@xilinx-zcu102-2018_2:~# echo 1 > /sys/class/fpga_manager/fpga0/flags
root@xilinx-zcu102-2018_2:~# echo off.bin > /sys/class/fpga_manager/fpga0/firmware
[  141.180427] fpga_manager fpga0: writing off.bin to Xilinx ZynqMP FPGA Manager
root@xilinx-zcu102-2018_2:~# devmem 0x80000000
0x00000000
root@xilinx-zcu102-2018_2:~#
root@xilinx-zcu102-2018_2:~# echo On.bin > /sys/class/fpga_manager/fpga0/firmware
[  196.508391] fpga_manager fpga0: writing On.bin to Xilinx ZynqMP FPGA Manager
root@xilinx-zcu102-2018_2:~# devmem 0x80000000
0x000000AA



Change Log
2016.3
Summary:
  • fpga manager Adding FPGA Manager support for Xilinx zynqmp Soc
  • fpga: Removed warning from zynqmp-fpga.c compilation.
Commits:
  • 280ca3f fpga manager: Adding FPGA Manager support for Xilinx zynqmp Soc
  • ad53092 fpga: Removed -warning from zynqmp-fpga.c compilation.

2016.4
  • None

2017.1
Summary:
  • fpga manager: Adopted Encrypted BitStream loading support for Xilinx ZynqMp.
  • fpga: zynqmp: Fix ZynqMP name in print.
  • fpga manager: Adopted Authenticated BitStream loading support for Xilinx.
  • fpga: zynqmp: Add fpga image information struct.
Commits:
  • a17a6e1 fpga manager: Adopted Encrypted BitStream loading support for Xilinx ZynqMp.
  • 7130ff7 fpga: zynqmp: Fix ZynqMP name in print.
  • ed5a141 fpga manager: Adopted Authenticated BitStream loading support for Xilinx.
  • b8bc48c fpga: zynqmp: Add fpga image information struct.

2017.2
  • None

2017.3
Summary:
  • zynqmp: Use new firmware.h instead of pm.h
  • Revert "fpga manager: Adopted Authenticated BitStream loading support for Xilinx"
Commits:
  • 5e81ba5 zynqmp: Use new firmware.h instead of pm.h
  • a7fbcf3 Revert "fpga manager: Adopted Authenticated BitStream loading support for Xilinx"

2017.4
  • None

2018.1
Summary:
  • soc: zynqmp: Define EEMI ops structure
  • soc: zynqmp: Use new firmware APIs
  • fpga: zynqmp: sync driver with xilfpga library enhancements
  • fpga: zynqmp: Remove useless blank line in zynqmp_fpga_remove
Commits:
  • 31c2a5e soc: zynqmp: Define EEMI ops structure
  • 0b7483c soc: zynqmp: Use new firmware APIs
  • 45ec97f fpga: zynqmp: sync driver with xilfpga library enhancements
  • fbf0102 fpga: zynqmp: Remove useless blank line in zynqmp_fpga_remove

2018.2
Summary:
  • Added Support for Partial Reconfiguration
Commits:
  • No Changes in the driver (Changes are done in the xilfpga library).

Related Links

https://github.com/Xilinx/linux-xlnx/blob/master/drivers/fpga/zynqmp-fpga.c