devicetree support for PCIe cards on x86

From: Suesens, Sebastian
Date: Mon Sep 09 2024 - 02:57:23 EST


Hi,

first, I want to explain why devicetree support for PCIe on x86 make sense and how I patched devicetree support on x86 for PCIe.

Why I require devicetree support?

I have a PCIe Card with an Ultrascale+ FPGA from AMD which has a PCIe Endpoint support. I implement in this example an GPIO and SPI interface on the FPGA.
For all this parts the Linux Kernel has drivers, but these drivers are only supported with devicetree support (exception of SPI).
Simply I want to use the Linux Kernel eco system.

I enabled "CONFIG_OF_EARLY_FLATTREE" and "CONFIG_PCI_DYNAMIC_OF_NODES" to get PCIe overlay support.
With the option of "CONFIG_OF_EARLY_FLATTREE" the file empty_root.dts is used for devicetree support. I patched a pci root-complex node in this file,
So that with option "CONFIG_PCI_DYNAMIC_OF_NODES" a PCIe tree is generated automatically.

I have to do some other parts in my driver see patch: https://patchwork.ozlabs.org/project/linux-pci/patch/20240430083730.134918-17-herve.codina@xxxxxxxxxxx/#3311787

For your information I work on Kernel 6.10.

I wrote this message for people who needs devicetree support for PCIe cards as well.
But the main reason is to get a real x86 devicetree interface into the Linux Kernel.

Regards, Sebastian


// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
/plugin/;

/ {
fragment@0 {
target-path="";
__overlay__ {
#address-cells = <3>;
#size-cells = <2>;

interrupt-parent = <&pcie_user_intc>;

pcie_user_intc: interrupt-controller {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
xdma,num-intr-inputs = <16>;
};

pci-ep-bus@0 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;

/*
* map @0x70900000 (256kB) to BAR0 (AXI)
* map @0x70940000 (64kB) to BAR1 (Config)
*/
ranges = <0x70900000 0x00 0x00 0x00 0x40000
0x70940000 0x01 0x00 0x00 0x1000>;

axi_gpio: gpio@70920000 {
compatible = "xlnx,xps-gpio-1.00.a";
reg = <0x70920000 0x1000>;
#gpio-cells = <2>;
xlnx,all-inputs = <0x0>;
xlnx,all-outputs = <0x0>;
xlnx,dout-default = <0x0>;
xlnx,gpio-width = <0x09>;
xlnx,interrupt-present = <0x0>;
xlnx,is-dual = <0x0>;
xlnx,tri-default = <0xFFFFFFFF>;
};

axi_spi: spi@70909000 {
#address-cells = <1>;
#size-cells = <0>;
bits-per-word = <8>;
compatible = "xlnx,axi-quad-spi-3.2", "xlnx,xps-spi-2.00.a";
fifo-size = <0>;
interrupt-names = "spi_irq";
interrupt-parent = <&pcie_user_intc>;
interrupts = <2>;
reg = <0x70909000 0x1000>;
xlnx,num-ss-bits = <0x3>;
xlnx,spi-mode = <0>;

spidev0: spi@0 {
compatible = "rohm,dh2228fv"; /* actually spidev for my_spi_dev */
reg = <0>;
spi-max-frequency = <100000>;
};

Spidev1: spi@1 {
compatible = "rohm,dh2228fv"; /* actually spidev for my_spi_dev */
reg = <1>;
spi-max-frequency = <100000>;
};
};
};
};
};
};