Xilinx Linux PL PCIe Root Port


This page gives an overview of Root Port driver for Xilinx XDMA (Bridge mode) IP, when connected to PCIe block in Zynq UltraScale+ MPSoC PL and PL PCIe4 in Versal Adaptive SoC.  The driver is available as part of Xilinx Linux distribution as drivers/pci/controller/pcie-xdma-pl.c

Table of Contents

XDMA IP

The documentation for XDMA IP is available in PG194. It is used in bridge mode for Root port.


Root Port Driver Configuration

The PCI/PCIe subsystem support in ZynqMP kernel configuration. For selecting XDMA PL PCIe root port driver enable CONFIG_PCIE_XDMA_PL option. (The driver file is same for both ZU+ MPSoC PL and Versal PL PCIe4)

ZynqMP XDMA PL PCIe Root Port:

Hardware setup

The hardware setup uses Xilinx ZCU106 hardware platform along with Root port FMC on HPC FMC slot. The design uses XDMA-bridge mode IP with PL-PCIe and targets GTs routed to HPC FMC.

The following features are supported:

  • Reception of legacy & MSI interrupts
  • 64-bit addressing i.e. BARs can be 32-bit or 64-bit on Endpoints

Tested End Points

1. Broadcom PCIe NIC card
2. Intel NVMe SSD
3. Intel NIC card

Standard PetaLinux build flow for Linux image/devicetree generation using HDF from hardware design should be followed.


End Point Driver Configuration


This page demonstrates the Root Port driver using Broadcom NIC Endpoint, for which NIC driver should be enabled in kernel as shown,



For other End point cards, ensure the respective driver is enabled in kernel.

Device Tree binding


The device tree node for AXI PCIe core will be automatically generated, if the core is configured in the HW design, using the Device Tree BSP.

Steps to generate device-tree is documented here,
http://www.wiki.xilinx.com/Build+Device+Tree+Blob

And a sample binding is shown below and the description of DT property is documented here

xdma_0: axi-pcie@a0000000 {
		#address-cells = <3>;
		#interrupt-cells = <1>;
		#size-cells = <2>;
		compatible = "xlnx,xdma-host-3.00";
		device_type = "pci";
		interrupt-map = <0 0 0 1 &pcie_intc_0 1>, <0 0 0 2 &pcie_intc_0 2>, <0 0 0 3 &pcie_intc_0 3>, <0 0 0 4 &pcie_intc_0 4>;
		interrupt-map-mask = <0 0 0 7>;
		interrupt-parent = <&gic>;
		interrupt-names = "misc", "msi0", "msi1";
		interrupts = <0 89 4>, <0 90 4>, <0 91 4>;
		ranges = <0x02000000 0x00000000 0xB0000000 0x0 0xB0000000 0x00000000 0x01000000>,
			<0x43000000 0x00000005 0x00000000 0x00000005 0x00000000 0x00000000 0x01000000>;
		reg = <0x0 0xA0000000 0x0 0x10000000>;
		pcie_intc_0: interrupt-controller {
			#address-cells = <0>;
			#interrupt-cells = <1>;
			interrupt-controller ;
		};
	};

Test Procedure

  • Boot linux onto ZCU106.
  • After successful booting of the linux, the Broadcom NIC endpoint driver is seen to be probed.
  • Run the command ‘lspci’ from the user prompt, which shows the the device id and vendor id of the Broadcom NIC card. This ensures the enumeration of the device is fine.
  • The Broadcom NIC is shown up as an eth0 interface in the linux. Run the command ‘ifconfig eth0 up’ which brings up the Ethernet interface. This step ensures all the memory transactions on the PCIe bus are working. (the ethX assigned may be dependent on other Ethernet ports enabled on your setup)
  • Assign a IP address either static/dhcp.
  • Ping to a device of known IP address.


Kernel Console Output


Driver Initialization for ZynqMP


[    1.568000] xilinx-pcie a0000000.axi-pcie: PCIe Link is UP
[    1.568019] OF: PCI: host bridge /amba_pl@0/axi-pcie@a0000000 ranges:
[    1.568034] OF: PCI:   No bus range found for /amba_pl@0/axi-pcie@a0000000, using [bus 00-ff]
[    1.568060] OF: PCI:   MEM 0xb0000000..0xb0ffffff -> 0xb0000000
[    1.568075] OF: PCI:   MEM 0x500000000..0x500ffffff -> 0x500000000
[    1.568176] xilinx-pcie a0000000.axi-pcie: PCI host bridge to bus 0000:00
[    1.568193] pci_bus 0000:00: root bus resource [bus 00-ff]
[    1.568207] pci_bus 0000:00: root bus resource [mem 0xb0000000-0xb0ffffff]
[    1.568222] pci_bus 0000:00: root bus resource [mem 0x500000000-0x500ffffff pref]
[    1.568257] pci 0000:00:00.0: [10ee:9114] type 01 class 0x060400
[    1.568279] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x3fffffff]
[    1.568414] pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.568512] pci 0000:01:00.0: [14e4:1677] type 00 class 0x020000
[    1.568552] pci 0000:01:00.0: reg 0x10: [mem 0x986220140a200000-0x986220140a20ffff 64bit]
[    1.568615] pci 0000:01:00.0: reg 0x30: [mem 0x06000000-0x0600ffff pref]
[    1.568716] pci 0000:01:00.0: PME# supported from D3hot
[    1.568835] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    1.568867] pci 0000:00:00.0: BAR 0: no space for [mem size 0x40000000]
[    1.568882] pci 0000:00:00.0: BAR 0: failed to assign [mem size 0x40000000]
[    1.568898] pci 0000:00:00.0: BAR 8: assigned [mem 0xb0000000-0xb00fffff]
[    1.568915] pci 0000:01:00.0: BAR 0: assigned [mem 0xb0000000-0xb000ffff 64bit]
[    1.568949] pci 0000:01:00.0: BAR 6: assigned [mem 0xb0010000-0xb001ffff pref]
[    1.568969] pci 0000:00:00.0: PCI bridge to [bus 01]
[    1.568984] pci 0000:00:00.0:   bridge window [mem 0xb0000000-0xb00fffff]
[    1.569773] xilinx-dpdma fd4c0000.dma: Xilinx DPDMA engine is probed
[    1.570058] Write failed gate address:1000f02
[    1.570150] xilinx-zynqmp-dma fd500000.dma: ZynqMP DMA driver Probe success
[    1.570276] xilinx-zynqmp-dma fd510000.dma: ZynqMP DMA driver Probe success
[    1.570401] xilinx-zynqmp-dma fd520000.dma: ZynqMP DMA driver Probe success
[    1.570525] xilinx-zynqmp-dma fd530000.dma: ZynqMP DMA driver Probe success
[    1.570651] xilinx-zynqmp-dma fd540000.dma: ZynqMP DMA driver Probe success
[    1.570777] xilinx-zynqmp-dma fd550000.dma: ZynqMP DMA driver Probe success
[    1.570903] xilinx-zynqmp-dma fd560000.dma: ZynqMP DMA driver Probe success
[    1.571028] xilinx-zynqmp-dma fd570000.dma: ZynqMP DMA driver Probe success
[    1.571227] xilinx-zynqmp-dma ffa80000.dma: ZynqMP DMA driver Probe success
[    1.571354] xilinx-zynqmp-dma ffa90000.dma: ZynqMP DMA driver Probe success
[    1.571482] xilinx-zynqmp-dma ffaa0000.dma: ZynqMP DMA driver Probe success
[    1.571625] xilinx-zynqmp-dma ffab0000.dma: ZynqMP DMA driver Probe success
[    1.571754] xilinx-zynqmp-dma ffac0000.dma: ZynqMP DMA driver Probe success
[    1.571881] xilinx-zynqmp-dma ffad0000.dma: ZynqMP DMA driver Probe success
[    1.572013] xilinx-zynqmp-dma ffae0000.dma: ZynqMP DMA driver Probe success
[    1.572139] xilinx-zynqmp-dma ffaf0000.dma: ZynqMP DMA driver Probe success
[    1.572304] zynqmp_pm firmware: Power management API v0.3
[    1.572413] xenfs: not registering filesystem on non-xen platform
[    1.598776] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    1.600017] ff000000.serial: ttyPS0 at MMIO 0xff000000 (irq = 41, base_baud = 6249375) is a xuartps
[    2.794394] console [ttyPS0] enabled
[    2.798278] ff010000.serial: ttyPS1 at MMIO 0xff010000 (irq = 42, base_baud = 6249375) is a xuartps
[    2.807433] [drm] Initialized
[    2.810641] [drm] load() is defered & will be called again
[    2.816506] xilinx-drm-dp-sub fd4aa000.dp_sub: Xilinx DisplayPort Subsystem is probed
[    2.824414] Unable to detect cache hierarchy from DT for CPU 0
[    2.834635] brd: module loaded
[    2.840268] loop: module loaded
[    2.854238] ahci-ceva fd0c0000.ahci: AHCI 0001.0301 32 slots 2 ports 6 Gbps 0x3 impl platform mode
[    2.863137] ahci-ceva fd0c0000.ahci: flags: 64bit ncq sntf pm clo only pmp fbs pio slum part ccc sds apst
[    2.873538] scsi host0: ahci-ceva
[    2.876965] scsi host1: ahci-ceva
[    2.880325] ata1: SATA max UDMA/133 mmio [mem 0xfd0c0000-0xfd0c1fff] port 0x100 irq 39
[    2.888173] ata2: SATA max UDMA/133 mmio [mem 0xfd0c0000-0xfd0c1fff] port 0x180 irq 39
[    2.896194] mtdoops: mtd device (mtddev=name/number) must be supplied
[    2.903439] m25p80 spi0.0: n25q512a (131072 Kbytes)
[    2.908248] 3 ofpart partitions found on MTD device spi0.0
[    2.913703] Creating 3 MTD partitions on "spi0.0":
[    2.918479] 0x000000000000-0x000000100000 : "boot"
[    2.923754] 0x000000100000-0x000000140000 : "bootenv"
[    2.929163] 0x000000140000-0x000001740000 : "kernel"
[    2.935211] libphy: Fixed MDIO Bus: probed
[    2.940201] tun: Universal TUN/TAP device driver, 1.6
[    2.945184] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[    2.951458] CAN device driver interface
[    2.956159] macb ff0e0000.ethernet: Not enabling partial store and forward
[    2.963345] libphy: MACB_mii_bus: probed
[    2.971086] macb ff0e0000.ethernet eth0: Could not attach to PHY
[    3.011805] tg3.c:v3.137 (May 11, 2014)
[    3.015577] pci 0000:00:00.0: enabling device (0000 -> 0002)

Broadcom NIC card probing

[    3.021218] tg3 0000:01:00.0: enabling device (0000 -> 0002)
[    3.058190] tg3 0000:01:00.0 eth0: Tigon3 [partno(BCM95751A519) rev 4101] (PCI Express) MAC address 00:07:13:04:3d:18
[    3.068733] tg3 0000:01:00.0 eth0: attached PHY is 5750 (10/100/1000Base-T Ethernet) (WireSpeed[1], EEE[0])
[    3.078450] tg3 0000:01:00.0 eth0: RXcsums[1] LinkChgREG[0] MIirq[0] ASF[0] TSOcap[1]
[    3.086261] tg3 0000:01:00.0 eth0: dma_rwctrl[76180000] dma_mask[64-bit]


Ethernet Interface

root@:~# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:07:13:04:3D:18
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:48


Testing of Ethernet interface

root@:~# ifconfig eth0 192.168.1.4
tg3 0000:01:00.0 eth0: Link is up at 1000 Mbps, full duplex
tg3 0000:01:00.0 eth0: Flow control is on for TX and on for RX
IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
 
root@:~# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data bytes
64 bytes from 192.168.1.2: seq=0 ttl=128 time=1.502 ms
64 bytes from 192.168.1.2: seq=1 ttl=128 time=1.131 ms
64 bytes from 192.168.1.2: seq=2 ttl=128 time=1.305 ms
64 bytes from 192.168.1.2: seq=3 ttl=128 time=0.699 ms
64 bytes from 192.168.1.2: seq=4 ttl=128 time=0.762 ms
64 bytes from 192.168.1.2: seq=5 ttl=128 time=0.736 ms
64 bytes from 192.168.1.2: seq=6 ttl=128 time=1.096 ms
64 bytes from 192.168.1.2: seq=7 ttl=128 time=0.680 ms
64 bytes from 192.168.1.2: seq=8 ttl=128 time=0.783 ms
64 bytes from 192.168.1.2: seq=9 ttl=128 time=0.885 ms
--- 192.168.1.2 ping statistics ---
10 packets transmitted, 10 packets received, 0% packet loss

Interrupts

root@:~# cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
  2:          0          0          0          0     GICv2  29 Level     arch_timer
  3:      17031       4305       1793       2036     GICv2  30 Level     arch_timer
 10:          0          0          0          0     GICv2  67 Level     zynqmp_pm
 13:          0          0          0          0     GICv2 156 Level     zynqmp-dma
 14:          0          0          0          0     GICv2 157 Level     zynqmp-dma
 15:          0          0          0          0     GICv2 158 Level     zynqmp-dma
 16:          0          0          0          0     GICv2 159 Level     zynqmp-dma
 17:          0          0          0          0     GICv2 160 Level     zynqmp-dma
 18:          0          0          0          0     GICv2 161 Level     zynqmp-dma
 19:          0          0          0          0     GICv2 162 Level     zynqmp-dma
 20:          0          0          0          0     GICv2 163 Level     zynqmp-dma
 22:          0          0          0          0     GICv2 109 Level     zynqmp-dma
 23:          0          0          0          0     GICv2 110 Level     zynqmp-dma
 24:          0          0          0          0     GICv2 111 Level     zynqmp-dma
 25:          0          0          0          0     GICv2 112 Level     zynqmp-dma
 26:          0          0          0          0     GICv2 113 Level     zynqmp-dma
 27:          0          0          0          0     GICv2 114 Level     zynqmp-dma
 28:          0          0          0          0     GICv2 115 Level     zynqmp-dma
 29:          0          0          0          0     GICv2 116 Level     zynqmp-dma
 33:          0          0          0          0     GICv2  49 Level     cdns-i2c
 34:          0          0          0          0     GICv2  50 Level     cdns-i2c
 35:          0          0          0          0     GICv2  42 Level     ff960000.memory-controller
 36:         14          0          0          0     GICv2  47 Level     ff0f0000.spi
 37:          0          0          0          0     GICv2  58 Level     ffa60000.rtc
 38:          0          0          0          0     GICv2  59 Level     ffa60000.rtc
 39:          0          0          0          0     GICv2 165 Level     ahci-ceva[fd0c0000.ahci]
 40:        144          0          0          0     GICv2  81 Level     mmc0
 41:        891          0          0          0     GICv2  53 Level     xuartps
 43:          0          0          0          0     GICv2 145 Edge      fd4d0000.watchdog
 44:          0          0          0          0     GICv2  88 Level     ams-irq
 45:          0          0          0          0     GICv2 151 Level     fd4a0000.dp
 46:          0          0          0          0     GICv2 154 Level     fd4c0000.dma
 47:        647          0          0          0     GICv2 121 Level     xilinx-pcie
 48:        647          0          0          0     dummy   1 Level     eth0
223:          0          0          0          0     GICv2  97 Level     xhci-hcd:usb1
IPI0:      1954        759       1664       2660       Rescheduling interrupts
IPI1:        63         57         71         43       Function call interrupts
IPI2:         0          0          0          0       CPU stop interrupts
IPI3:       349       2284       2398       2370       Timer broadcast interrupts
IPI4:         3          0          0          0       IRQ work interrupts
IPI5:         0          0          0          0       CPU wake-up interrupts
Err:          0




QDMA IP

The documentation for QDMA IP is available in PG344. It is used in bridge mode for Root port.


Root Port Driver Configuration

The PCI/PCIe subsystem support in Versal kernel configuration. For selecting QDMA PL PCIe root port driver enable CONFIG_PCIE_XDMA_PL option.

Versal QDMA PL PCIe4 Root Port:

Please refer AR76647 to add QDMA related driver patch and sample device tree.

Hardware setup

The design uses QDMA-bridge mode IP with Versal PL-PCIe4.

The following features are supported:

  • Reception of legacy & MSI interrupts
  • 32-bit BAR support

Tested End Points

1. Broadcom PCIe NIC card
2. Samsung 970 Evo SSD
3. Samsung 980 EVO SSD
4. Intel SSD

Standard Petalinux build flow for Linux image/devicetree generation using XSA from hardware design should be followed.


End Point Driver Configuration


The following driver is needed to be enabled for using NVMe SSD as EndPoint.



For other End point cards, ensure the respective driver is enabled in kernel.

Device Tree binding


And a sample binding is shown below and the description of DT property is documented here

     pcie_dma_versal_0: axi-pcie@80000000 {
                        #address-cells = <3>;
                        #interrupt-cells = <1>;
                        #size-cells = <2>;
                        compatible = "xlnx,qdma-host-3.00";
                        device_type = "pci";
                        interrupt-map = <0 0 0 1 &psv_pcie_intc_0 1>, <0 0 0 2 &psv_pcie_intc_0 2>, <0 0 0 3 &psv_pcie_intc_0 3>, <0 0 0 4 &psv_pcie_intc_0 4>;
                        interrupt-map-mask = <0 0 0 7>;
                        interrupt-names = "misc", "msi0", "msi1";
                        interrupt-parent = <&gic>;
                        interrupts = <0 84 4 0 85 4 0 86 4>;
                        ranges = <0x02000000 0x00000000 0xA8000000 0x0 0xA8000000 0x00000000 0x1000000>;
                        reg = <0x0 0x90000000 0x0 0x5000>,
                                <0x0 0x80000000 0x0 0x1000000>;
                        reg-names = "breg", "cfg";

                        psv_pcie_intc_0: interrupt-controller {
                                #address-cells = <0>;
                                #interrupt-cells = <1>;
                                interrupt-controller ;
                        };
                };

Test Procedure

  • Boot linux onto Versal.
  • Check lspci to confirm NVMe card is detected and do the following steps.
    • mount /dev/nvmeXX  /mnt
    • cd /mnt
    • dd if=/dev/zero of=tmp.txt bs=4096 count=200000

Kernel Console Output


Driver Initialization for Versal


[ 3.122832] io scheduler mq-deadline registered
[ 3.127401] io scheduler kyber registered
[ 3.131713] xilinx-xdma-pcie 90000000.axi-pcie: host bridge /amba_pl@0/axi-pcie@80000000 ranges:
[ 3.140586] xilinx-xdma-pcie 90000000.axi-pcie: No bus range found for /amba_pl@0/axi-pcie@80000000, using [bus 00-ff]
[ 3.151569] xilinx-xdma-pcie 90000000.axi-pcie: MEM 0x00a8000000..0x00a80fffff -> 0x00a8000000
[ 3.160775] xilinx-xdma-pcie 90000000.axi-pcie: PCIe Link is UP
[ 3.166841] xilinx-xdma-pcie 90000000.axi-pcie: PCI host bridge to bus 0000:00
[ 3.174134] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 3.179668] pci_bus 0000:00: root bus resource [mem 0xa8000000-0xa80fffff]
[ 3.186620] pci 0000:00:00.0: [10ee:b048] type 01 class 0x060400
[ 3.192688] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0xffffffff 64bit pref]
[ 3.200006] pci 0000:00:00.0: PME# supported from D3cold
[ 3.205838] pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[ 3.213973] pci 0000:01:00.0: [144d:a808] type 00 class 0x010802
[ 3.220054] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00003fff 64bit]
[ 3.227467] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[ 3.234150] pci 0000:00:00.0: BAR 0: no space for [mem size 0x100000000 64bit pref]
[ 3.241877] pci 0000:00:00.0: BAR 0: failed to assign [mem size 0x100000000 64bit pref]
[ 3.249949] pci 0000:00:00.0: BAR 8: assigned [mem 0xa8000000-0xa80fffff]
[ 3.256794] pci 0000:01:00.0: BAR 0: assigned [mem 0xa8000000-0xa8003fff 64bit]
[ 3.264179] pci 0000:00:00.0: PCI bridge to [bus 01]
[ 3.269189] pci 0000:00:00.0: bridge window [mem 0xa8000000-0xa80fffff]
[ 3.276445] ps_pcie_dma init()
[ 3.295314] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 3.302325] Serial: AMBA driver
[ 3.306196] cacheinfo: Unable to detect cache hierarchy for CPU 0

NVMe card probing

[ 4.709047] nvme nvme0: pci function 0000:01:00.0
[ 4.710192] pci 0000:00:00.0: enabling device (0000 -> 0002)
[ 4.715796] nvme 0000:01:00.0: enabling device (0000 -> 0002)


Testing of NVMe Access

root@:~# mount /dev/nvme0n1  /mnt
cd /mnt
dd if=/dev/zero of=tmp.txt bs=4096 count=200000

Interrupts

root@:/mnt# cat /proc/interrupts 
           CPU0       CPU1       
 11:       8828      22802     GICv3  30 Level     arch_timer
 14:          0          0     GICv3  92 Level     zynqmp-dma
 15:          0          0     GICv3  93 Level     zynqmp-dma
 16:          0          0     GICv3  94 Level     zynqmp-dma
 17:          0          0     GICv3  95 Level     zynqmp-dma
 18:          0          0     GICv3  96 Level     zynqmp-dma
 19:          0          0     GICv3  97 Level     zynqmp-dma
 20:          0          0     GICv3  98 Level     zynqmp-dma
 21:          0          0     GICv3  99 Level     zynqmp-dma
 23:          0          0     GICv3 174 Level     f12a0000.rtc
 24:          0          0     GICv3 175 Level     f12a0000.rtc
 25:       2428          0     GICv3  50 Level     uart-pl011
 27:          0          0     GICv3 176 Level     sysmon-irq
 28:          0          0     GICv3  62 Level     zynqmp_ipi
 29:          0          0     GICv3 116 Level     xilinx-pcie
 34:       4786          0  xilinx_pcie:msi 524288 Edge      nvme0q0, nvme0q1
IPI0:       211        247       Rescheduling interrupts
IPI1:      1080       2723       Function call interrupts
IPI2:         0          0       CPU stop interrupts
IPI3:         0          0       CPU stop (for crash dump) interrupts
IPI4:         0          0       Timer broadcast interrupts
IPI5:         0          0       IRQ work interrupts
IPI6:         0          0       CPU wake-up interrupts
Err:          0



Related Links


© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy