]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
PCI: dwc: Use devicetree 'reg[config]' to derive CPU -> ATU addr offset
authorFrank Li <Frank.Li@nxp.com>
Sat, 15 Mar 2025 20:15:42 +0000 (15:15 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 24 Mar 2025 19:58:34 +0000 (14:58 -0500)
The 'ranges' property of a PCI controller's parent can indicate address
translation information. Most system use 1:1 map between CPU physical and
PCI controller input addresses.

But some hardware, like i.MX8QXP, doesn't use 1:1 map.  See below diagram:

              ┌─────────┐                    ┌────────────┐
   ┌─────┐    │         │ IA: 0x8ff8_0000    │            │
   │ CPU ├───►│   ┌────►├─────────────────┐  │ PCI        │
   └─────┘    │   │     │ IA: 0x8ff0_0000 │  │            │
    CPU Addr  │   │  ┌─►├─────────────┐   │  │ Controller │
  0x7ff8_0000─┼───┘  │  │             │   │  │            │
              │      │  │             │   │  │            │   PCI Addr
  0x7ff0_0000─┼──────┘  │             │   └──► IOSpace   ─┼────────────►
              │         │             │      │            │    0
  0x7000_0000─┼────────►├─────────┐   │      │            │
              └─────────┘         │   └──────► CfgSpace  ─┼────────────►
               Bus Fabric         │          │            │    0
                                  │          │            │
                                  └──────────► MemSpace  ─┼────────────►
                          IA: 0x8000_0000    │            │  0x8000_0000
                                             └────────────┘

  bus@5f000000 {
          compatible = "simple-bus";
          #address-cells = <1>;
          #size-cells = <1>;
          ranges = <0x80000000 0x0 0x70000000 0x10000000>;

          pcie@5f010000 {
                  compatible = "fsl,imx8q-pcie";
                  reg = <0x5f010000 0x10000>, <0x8ff00000 0x80000>;
                  reg-names = "dbi", "config";
                  ...
          };
  };

Intermediate address (IA) here means the PCIe controller input address.
The pcie@5f010000 'reg[config]' address is the parent bus (PCIe controller
input) address of CfgSpace.

The ATU in MemSpace is not explicitly described via devicetree, so we
assume the offset from CPU address to intermediate MemSpace address is the
same as that for CfgSpace.

We could use bus@5f000000 'ranges' for the same purpose.

Set parent_bus_offset using dw_pcie_init_parent_bus_offset().  The
parent_bus_offset is not used yet, so no functional change intended.

Link: https://lore.kernel.org/r/20250315201548.858189-8-helgaas@kernel.org
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/controller/dwc/pcie-designware-host.c
drivers/pci/controller/dwc/pcie-designware.h

index 9ce06b1ee26682d45a7ef697b1e055f1550bf0e5..9e38ac7d1bcb707ddd465630afc7addb98b97a4e 100644 (file)
@@ -452,6 +452,12 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
                pp->io_base = pci_pio_to_address(win->res->start);
        }
 
+       /*
+        * visconti_pcie_cpu_addr_fixup() uses pp->io_base, so we have to
+        * call dw_pcie_parent_bus_offset() after setting pp->io_base.
+        */
+       pci->parent_bus_offset = dw_pcie_parent_bus_offset(pci, "config",
+                                                          pp->cfg0_base);
        return 0;
 }
 
index f08d2852cfd590d0b1837645b5dbbcacd5d6cc46..741c46926ce268d128fee800ccac8866e3abe4b9 100644 (file)
@@ -445,6 +445,7 @@ struct dw_pcie {
        void __iomem            *atu_base;
        resource_size_t         atu_phys_addr;
        size_t                  atu_size;
+       resource_size_t         parent_bus_offset;
        u32                     num_ib_windows;
        u32                     num_ob_windows;
        u32                     region_align;