PCI: dwc: Make cpu_addr_fixup take struct dw_pcie as argument
authorNiklas Cassel <niklas.cassel@axis.com>
Tue, 19 Dec 2017 23:29:36 +0000 (00:29 +0100)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Thu, 21 Dec 2017 11:10:34 +0000 (11:10 +0000)
The current cpu addr fixup mask for ARTPEC-6, GENMASK(27, 0), is wrong.
The correct cpu addr fixup mask for ARTPEC-6 is GENMASK(28, 0).

However, having a hardcoded cpu addr fixup mask in each driver is
arguably wrong.
A device tree property called something like "cpu-addr-fixup-mask"
would have been a better solution.
Introducing such a property is not needed though, since we already have
pp->cfg0_base and ep->phys_base, which is derived from already existing
device tree properties.

It is also worth noting that for ARTPEC-7, hardcoding the cpu addr fixup
mask is not possible, since it uses a High Address Bits Look Up Table,
which means that it can, at runtime, map the PCIe window to an arbitrary
address in the 32-bit address space.

By using pp->cfg0_base and ep->phys_base, we avoid hardcoding a mask
in each driver. This should work for ARTPEC-6, DRA7xx, and ARTPEC-7.
I have not changed the code in DRA7xx though, since their existing
code works, but if they want, they could use the same logic as
artpec6_pcie_cpu_addr_fixup, and thus remove their hardcoded mask.

The reason why the fixup mask is needed is explained in commit f4c55c5a3f7f
("PCI: designware: Program ATU with untranslated address").

Signed-off-by: Niklas Cassel <niklas.cassel@axis.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
drivers/pci/dwc/pci-dra7xx.c
drivers/pci/dwc/pcie-artpec6.c
drivers/pci/dwc/pcie-designware.c
drivers/pci/dwc/pcie-designware.h

index 6a5ccd447615a0c4a302f859c7e6f16f4061693f..4ab113543923c92d9d78e94284b02c4fd65add2c 100644 (file)
@@ -110,7 +110,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
        writel(value, pcie->base + offset);
 }
 
-static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr)
+static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
 {
        return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
 }
index e7de4e4649eb9f9f9171148e198c7aebdba1fefd..318a2bd0d97e063e17fe07962011494daab00ba3 100644 (file)
@@ -67,8 +67,6 @@ static const struct of_device_id artpec6_pcie_of_match[];
 #define PHY_STATUS                     0x118
 #define  PHY_COSPLLLOCK                        BIT(0)
 
-#define ARTPEC6_CPU_TO_BUS_ADDR                GENMASK(27, 0)
-
 static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset)
 {
        u32 val;
@@ -82,9 +80,21 @@ static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u
        regmap_write(artpec6_pcie->regmap, offset, val);
 }
 
-static u64 artpec6_pcie_cpu_addr_fixup(u64 pci_addr)
+static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
 {
-       return pci_addr & ARTPEC6_CPU_TO_BUS_ADDR;
+       struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+       struct pcie_port *pp = &pci->pp;
+       struct dw_pcie_ep *ep = &pci->ep;
+
+       switch (artpec6_pcie->mode) {
+       case DW_PCIE_RC_TYPE:
+               return pci_addr - pp->cfg0_base;
+       case DW_PCIE_EP_TYPE:
+               return pci_addr - ep->phys_base;
+       default:
+               dev_err(pci->dev, "UNKNOWN device type\n");
+       }
+       return pci_addr;
 }
 
 static int artpec6_pcie_establish_link(struct dw_pcie *pci)
index 88abdddee2ad7194e2efaebc6e3ba16dd6c95717..800be7a4f087516609876aa76799870ec0302814 100644 (file)
@@ -149,7 +149,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
        u32 retries, val;
 
        if (pci->ops->cpu_addr_fixup)
-               cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr);
+               cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
 
        if (pci->iatu_unroll_enabled) {
                dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
index 24edac03516006e343b748242f66a5468ab5f3e9..cca5a81c1c7439bfd61bd5f49ff7b63439f59258 100644 (file)
@@ -205,7 +205,7 @@ struct dw_pcie_ep {
 };
 
 struct dw_pcie_ops {
-       u64     (*cpu_addr_fixup)(u64 cpu_addr);
+       u64     (*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr);
        u32     (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
                            size_t size);
        void    (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,