Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a Device-Tree for the hardware on a PCI device

I'm in the process of writing a Linux device-driver for some custom hardware controlled via a PCIe card. The PCIe card contains an FPGA implementing SPI and I2C bus masters along with other custom firmware. There are already platform-bus device-drivers in the kernel for a lot of the hardware and I'd like to avoid duplicating that work.

Is there any way of creating a Device-Tree to describe the hardware on the card?

My thinking was that as the card is discovered and probed, it would map the BARS, register the device-tree and have the existing drivers pick-up the mapped address regions and provide interfaces to the hardware.

like image 226
RichC Avatar asked Jan 30 '26 23:01

RichC


1 Answers

Here is a snippet of a PCI device (VID,PID: 1234,5678) present on pci0 of an ARM board:

&pci0 {
    pci0,0 {
        #address-cells = <3>;
        #size-cells = <2>;
        reg = <0 0 0 0 0>;
        device_type = "pci";
        ranges = <0x82000000 0x0 0x40000000 0x82000000 0x0 0x40000000 0 0x40000000>;

        fpga@0 {
            compatible = "pci1234,5678";

            reg = <0x0000 0 0 0 0>;
            #address-cells = <1>;
            #size-cells = <1>;
            ranges = <0 0x82000000 0x0 0x48000000 0x2000000>;

            i2c@100400 {
                compatible = "snps,designware-i2c";
                reg = <0x100400 0x100>;
                #address-cells = <1>;
                #size-cells = <0>;
                interrupts = <8>;
                i2c-sda-hold-time-ns = <300>;
                clock-frequency = <100000>;
            };

            spi@101000 {
                compatible = "snps,dw-apb-ssi";
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x101000 0x1000>, <0x3c 0x18>;
                interrupts = <10>;

                flash@0 {
                    compatible = "mx25l25635e", "jedec,spi-nor";
                    spi-max-frequency = <20840000>;
                    reg = <0>;
                };
            };
        };
    };
};

This was working on a kernel v4.19 and may have been broken since. The main issue is that the PCI translation of device tree adresses is not quite right and so has to be done using the ranges property which ends up making the DT snippet device specific.

like image 135
Alexandre Belloni Avatar answered Feb 02 '26 12:02

Alexandre Belloni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!