How to interpret the PCIe registers and (address) ranges in device tree files?

0

I was trying to understand the reg and ranges fields in the following dts and tried to find the resemblance with already explained literature like PCI_Address_Translation and pcie device tree 'ranges' property explanation, but the number of cells are different i.e. six vs seven. How can I interpret these fields? Here is the dts file:

        pcie: pcie@fd0e0000 {
        compatible = "xlnx,nwl-pcie-2.11";
        status = "disabled";
        #address-cells = <3>;
        #size-cells = <2>;
        #interrupt-cells = <1>;
        msi-controller;
        device_type = "pci";
        interrupt-parent = <&gic>;
        interrupts = <0 118 4>,
                 <0 117 4>,
                 <0 116 4>,
                 <0 115 4>, /* MSI_1 [63...32] */
                 <0 114 4>; /* MSI_0 [31...0] */
        interrupt-names = "misc", "dummy", "intx",
                  "msi1", "msi0";
        msi-parent = <&pcie>;
        reg = <0x0 0xfd0e0000 0x0 0x1000>,
              <0x0 0xfd480000 0x0 0x1000>,
              <0x80 0x00000000 0x0 0x1000000>;
        reg-names = "breg", "pcireg", "cfg";
        ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000  /* non-prefetchable memory */
              0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */
        bus-range = <0x00 0xff>;
        interrupt-map-mask = <0x0 0x0 0x0 0x7>;
        interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>,
                <0x0 0x0 0x0 0x2 &pcie_intc 0x2>,
                <0x0 0x0 0x0 0x3 &pcie_intc 0x3>,
                <0x0 0x0 0x0 0x4 &pcie_intc 0x4>;
        power-domains = <&pd_pcie>;
        pcie_intc: legacy-interrupt-controller {
            interrupt-controller;
            #address-cells = <0>;
            #interrupt-cells = <1>;
        };
    };
linux-device-driver
device-tree
pci-e
asked on Stack Overflow Apr 28, 2020 by Techie Fort

1 Answer

0

Here is the boilerplate comment that is missing from your file:

/*
 * EEEEEEEEEE address properties encoded
 * p          PCI address upper 32 bits
 * PPPPPPPPPP PCI address lower 32 bits
 * ccc        CPU address upper 32 bits
 * CCCCCCCCCC CPU address lower 32 bits
 * s          range size upper 32 bits
 * SSSSSSSSSS range size lower 32 bits
 *
 * EEEEEEEEEE p PPPPPPPPPP ccc CCCCCCCCCC s SSSSSSSSSS
 */

Why 6 vs 7? Some PCI controllers only support 32 bits addresses. Same goes for CPU addresses. So for them having an additional field for "PCI address upper 32 bits" makes no sense. Refer to your system documentation to determine how wide your PCI controller is and how wide your address translation unit is (how many nibbles in the upper addresses are usable).

The "address properties encoded" is often just a magic number to tell the driver the type of range you are configuring.

answered on Stack Overflow Sep 19, 2020 by Not Saying

User contributions licensed under CC BY-SA 3.0