Solution Versal PL Programming

Introduction‍

The Versal Programmable Logic (PL) can be programmed either using U-Boot or through Linux.
This page provides the details about programming the PL from Linux world using Linux FPGA Manager framework.

Flow:

 

HW IP Features

  • Full Bitstream and Partial Bitstream/PDI loading

  • Encrypted and Authenticated Full/Partial Bitstream/PDI loading

  • Readback of Configuration Data

Features supported in the driver

  • Full Bitstream Support (DFx flow)

    • Non Secure Bitstream/PDI loading 

    • Encrypted  Bitstream/PDI loading with device-key

    • Authenticated Bitstream/PDI 

    • Authenticated and Encrypted Bitstream/PDI with device-key

  • Partial Bitstream Support 

    • Non Secure Bitstream/PDI loading 

    • Encrypted Partial Bitstream/PDI loading with device-key

    • Authenticated Partial Bitstream/PDI

    • Authenticated and Encrypted Partial Bitstream/PDI with device-key

Unsupported features in the driver

  • Full Bitstream Support 

    • Encrypted  Bitstream/PDI loading with user-key

    • Authenticated and Encrypted Bitstream/PDI  loading with User-key

  • Partial Bitstream Support 

    • Encrypted Partial Bitstream/PDI with user-key

    • Authenticated and Encrypted Partial Bitstream/PDI  with user-key

  •  Read Back Support

    • Configuration Data Readback.

Missing Features, Known Issues and Limitations in the driver

  • No tool flow support for Bitstream Bitstream loading using Overlay (DTG, Petalinux and Yocto)

Note 1: 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 Petalinux release. 
              

Note 2: Axi Interrupt controller driver doesn't work as kernel modules/overlay like other device drivers due to the below limitation

                    Interrupt controller driver uses to register with . So it will follow the below sequence to invoke the xilinx_intc_of_init) (callback function)

                           start_kernel) –> init_IRQ) --> irqchip_init) --> of_irq_init) --> call-back functionxilinx_intc_of_init)

                   If The Driver was registered using IRQCHIP_DECLARE  it must be compiled into the kernel and the callback function will be invoked at kernel boot time.

 

Kernel Configuration

The following config options to be enabled in order to use FPGA Manager, Please note that these options are enabled by default  through xilinx_versal_defconfig except for the option. If user wants to test feature they have it.

Versal FPGA Manager Configuration:

Select: Device Drivers → FPGA Configuration Framework →   Xilinx Versal FPGA 

 

In-order to test feature user needs to enable FPGA debug  

Select: Device Drivers →  FPGA Configuration Framework -->   FPGA debug  fs

 

DT overlay ConfigFS interface Configuration:
In-order to load Bitstream with DTBO user needs to enable below options

Select: Device Drivers --> Device Tree and Open Firmware support

 

Contiguous Memory Allocator Configuration:

1 CONFIG_CMA

Select: Kernel Features --> Contiguous Memory Allocator

1 CONFIG_DMA_CMA

Select: Device Drivers --> Generic Driver Options → DMA Contiguous Memory Allocator 

 

Devicetree

1 2 3 4 5 6 7 8 9 10 versal_fpga: versal_fpga { compatible = "xlnx,versal-fpga"; }; fpga: fpga { compatible = "fpga-region"; fpga-mgr = <&versal_fpga>; #address-cells = <2>; #size-cells = <2>; };

FPGA Programming

Steps for programming the Bitstream/PDI using sysfs 

Load the Bitstream/PDI

  • mkdir -p /lib/firmware

  • cp /media/Bitstream.pdi /lib/firmware/

  • echo Bitstream.pdi > /sys/class/fpga_manager/fpga0/firmware

Steps for programming the Bistream/PDI using overlay

There is no out-of-box tool flow support for loading Bitstreams/PDI's that need PL drivers. The creation of DTO files needed for this approach is not supported in the tool flow (DTG, Petalinux, Yocto).

Users can still achieve their goal of programming the bitstreams that need PL driver support by using hand-written DTSi files.

Copy the Bitstream/PDI (.pdi) and pl.dtbo files into lib/firmware folder

  • mkdir /configfs

  • mount -t configfs configfs /configfs

  • cd /configfs/device-tree/overlays/

  • mkdir Bitstream

  • echo -n "pl.dtbo" > Bitstream/path

Steps to remove the drivers got added as part of DTO

  • rmdir /configfs/device-tree/overlays/Bitstream


Compiling pl.dtsi (object)

1 dtc -O dtb -o pl.dtbo -b 0 -@ pl.dtsi

Device-tree overlay file contents example:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 //Device Tree Example // Enable the axi-gpio interface /dts-v1/; /plugin/; / {     fragment@0 { /* Bitstream  Fragment */         target = <&fpga>;         overlay0: __overlay__ {             #address-cells = <2>;             #size-cells = <2>;             firmware-name = "Bitstream.pdi";         };     };     fragment@2 { /* PL Drivers Fragment */         target = <&amba>;         overlay2: __overlay__ {             axi_gpio_0: gpio@a0000000 {                 #gpio-cells = <3>;                 #interrupt-cells = <2>;                 clock-names = "s_axi_aclk";                 clocks = <&clk 71>;                 compatible = "xlnx,axi-gpio-2.0", "xlnx,xps-gpio-1.00.a";                 gpio-controller ;                 -controller ;                 interrupt-names = "ip2intc_irpt";                 interrupt-parent = <&gic>;                 interrupts = <0 89 4>;                 reg = <0x0 0xa0000000 0x0 0x1000>;                 all-inputs = <0x1>;                 all-inputs-2 = <0x0>;                 all-outputs = <0x0>;                 all-outputs-xlnx,2 = <0x1>;                 dout-xlnx,default = <0x00000000>;                 dout-default-2 = <0xAAAAAAAA>;                 gpio-width = <0x8>;                 xlnx,gpio2-width = <0x8>;                 xlnx,interrupt-present = <0x1>;                 xlnx,is-dual = <xlnx,xlnx,0x1>;                 xlnx,tri-xlnx,xlnx,default = <0xFFFFFFFF>;                 xlnx,tri-xlnx,xlnx,default-2 = <0xFFFFFFFF>;             };             psu_ctrl_ipi: PERIPHERAL@ff380000 {                 /* This is a place holder node for a custom IP, user may need to update the entries */                 compatible =compatible "PERIPHERAL-1.0",xlnx,xlnx;                 reg = <0x0 0xff380000 0x0 0x80000>;             };             psu_message_buffers: PERIPHERAL@ff990000 {                 /* This is a place holder node for a custom IP, user may need to update the entries */                 compatible =compatible "xlnx,PERIPHERAL-1.0"xlnx,;                 reg = <0x0 0xff990000 0x0 0x10000>;             };         };     }; };

Steps for programming the Bitstream/PDI using Debug fs

  • mount -t debugfs none /sys/kernel/debug/

  • mkdir -p /lib/firmware

  • cp /media/Bitstream.pdi /lib/firmware/

  • 1 2 dd bs=16M if=/lib/firmware/Bitstream.pdi of=/sys/kernel/debug/fpga/fpga0/load (where Bitstream.pdi < 16M)

Steps for programming the Bitstream/PDI using fpgautil 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 root@xilinx:~# fpgautil -h fpgautil: FPGA Utility for Loading/reading PL Configuration in zynqMP Usage: fpgautil -b <bin file path> -o <dtbo file path> Options: -b <binfile> (Bin file path) -o <dtbofile> (DTBO file path) -f <flags> Optional: <Bitstream type flags> f := <Full | Partial > Default: <Full> Examples: (Load Full Bitstream using Overlay) fpgautil -b top.bit.bin -o can.dtbo (Load Partial Bitstream through the sysfs interface) fpgautil -b top.bit.bin -f Partial

 

Loading an overlay along with it's Bitstream

Usage: fpgautil -b <bin file path> -o <overlay file path> 

Removing an overlay

Usage: fpgautil -R 

Loading Bitstream only

Usage: fpgautil -b <bit/bin/PDI file absolute path> 

Mainline Status

  • This driver is currently not available in the mainline kernel

Release history

2020.2

Summary:

  • fpga: versal: Initialized variables before using it

  • fpga: versal: Use the scatterlist interface

  • fpga: versal: Use 32-bit DMA addressing

  • fpga: versal-fpga: Add versal fpga manager driver

Commits:

  • 8ab35bd fpga: versal: Initialized variables before using it

  • 3512d8c fpga: versal: Use the scatterlist interface

  • 4cb67d7 fpga: versal: Use 32-bit DMA addressing

  • ab30062 fpga: versal-fpga: Add versal fpga manager driver

References

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

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