aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Cassel <niklas.cassel@axis.com>2017-12-19 18:29:36 -0500
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2017-12-21 06:10:34 -0500
commitb6900aeb1977ee1430578ce8b373e5c9fc6366d5 (patch)
tree369ac88c88bbb68309043e6066095d2ba5a65495
parentb5074ef6fe7d6ed4bb8cd8660907b3092b8ae325 (diff)
PCI: dwc: Make cpu_addr_fixup take struct dw_pcie as argument
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>
-rw-r--r--drivers/pci/dwc/pci-dra7xx.c2
-rw-r--r--drivers/pci/dwc/pcie-artpec6.c18
-rw-r--r--drivers/pci/dwc/pcie-designware.c2
-rw-r--r--drivers/pci/dwc/pcie-designware.h2
4 files changed, 17 insertions, 7 deletions
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index 6a5ccd447615..4ab113543923 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -110,7 +110,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
110 writel(value, pcie->base + offset); 110 writel(value, pcie->base + offset);
111} 111}
112 112
113static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr) 113static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
114{ 114{
115 return pci_addr & DRA7XX_CPU_TO_BUS_ADDR; 115 return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
116} 116}
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index e7de4e4649eb..318a2bd0d97e 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -67,8 +67,6 @@ static const struct of_device_id artpec6_pcie_of_match[];
67#define PHY_STATUS 0x118 67#define PHY_STATUS 0x118
68#define PHY_COSPLLLOCK BIT(0) 68#define PHY_COSPLLLOCK BIT(0)
69 69
70#define ARTPEC6_CPU_TO_BUS_ADDR GENMASK(27, 0)
71
72static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset) 70static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset)
73{ 71{
74 u32 val; 72 u32 val;
@@ -82,9 +80,21 @@ static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u
82 regmap_write(artpec6_pcie->regmap, offset, val); 80 regmap_write(artpec6_pcie->regmap, offset, val);
83} 81}
84 82
85static u64 artpec6_pcie_cpu_addr_fixup(u64 pci_addr) 83static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
86{ 84{
87 return pci_addr & ARTPEC6_CPU_TO_BUS_ADDR; 85 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
86 struct pcie_port *pp = &pci->pp;
87 struct dw_pcie_ep *ep = &pci->ep;
88
89 switch (artpec6_pcie->mode) {
90 case DW_PCIE_RC_TYPE:
91 return pci_addr - pp->cfg0_base;
92 case DW_PCIE_EP_TYPE:
93 return pci_addr - ep->phys_base;
94 default:
95 dev_err(pci->dev, "UNKNOWN device type\n");
96 }
97 return pci_addr;
88} 98}
89 99
90static int artpec6_pcie_establish_link(struct dw_pcie *pci) 100static int artpec6_pcie_establish_link(struct dw_pcie *pci)
diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
index 88abdddee2ad..800be7a4f087 100644
--- a/drivers/pci/dwc/pcie-designware.c
+++ b/drivers/pci/dwc/pcie-designware.c
@@ -149,7 +149,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
149 u32 retries, val; 149 u32 retries, val;
150 150
151 if (pci->ops->cpu_addr_fixup) 151 if (pci->ops->cpu_addr_fixup)
152 cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr); 152 cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
153 153
154 if (pci->iatu_unroll_enabled) { 154 if (pci->iatu_unroll_enabled) {
155 dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr, 155 dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
index 24edac035160..cca5a81c1c74 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -205,7 +205,7 @@ struct dw_pcie_ep {
205}; 205};
206 206
207struct dw_pcie_ops { 207struct dw_pcie_ops {
208 u64 (*cpu_addr_fixup)(u64 cpu_addr); 208 u64 (*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr);
209 u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, 209 u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
210 size_t size); 210 size_t size);
211 void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, 211 void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,