aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/dwc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/dwc')
-rw-r--r--drivers/pci/dwc/Kconfig70
-rw-r--r--drivers/pci/dwc/Makefile6
-rw-r--r--drivers/pci/dwc/pci-dra7xx.c47
-rw-r--r--drivers/pci/dwc/pci-exynos.c227
-rw-r--r--drivers/pci/dwc/pci-imx6.c5
-rw-r--r--drivers/pci/dwc/pci-keystone-dw.c6
-rw-r--r--drivers/pci/dwc/pci-keystone.c10
-rw-r--r--drivers/pci/dwc/pci-keystone.h6
-rw-r--r--drivers/pci/dwc/pci-layerscape.c5
-rw-r--r--drivers/pci/dwc/pcie-armada8k.c5
-rw-r--r--drivers/pci/dwc/pcie-artpec6.c475
-rw-r--r--drivers/pci/dwc/pcie-designware-ep.c140
-rw-r--r--drivers/pci/dwc/pcie-designware-host.c20
-rw-r--r--drivers/pci/dwc/pcie-designware-plat.c5
-rw-r--r--drivers/pci/dwc/pcie-designware.c7
-rw-r--r--drivers/pci/dwc/pcie-designware.h41
-rw-r--r--drivers/pci/dwc/pcie-hisi.c5
-rw-r--r--drivers/pci/dwc/pcie-histb.c5
-rw-r--r--drivers/pci/dwc/pcie-kirin.c5
-rw-r--r--drivers/pci/dwc/pcie-qcom.c14
-rw-r--r--drivers/pci/dwc/pcie-spear13xx.c5
21 files changed, 654 insertions, 455 deletions
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index 113e09440f85..0f666b1ce289 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -1,3 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0
2
1menu "DesignWare PCI Core Support" 3menu "DesignWare PCI Core Support"
2 4
3config PCIE_DW 5config PCIE_DW
@@ -15,39 +17,38 @@ config PCIE_DW_EP
15 select PCIE_DW 17 select PCIE_DW
16 18
17config PCI_DRA7XX 19config PCI_DRA7XX
18 bool "TI DRA7xx PCIe controller" 20 bool
19 depends on SOC_DRA7XX || COMPILE_TEST
20 depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT
21 depends on OF && HAS_IOMEM && TI_PIPE3
22 help
23 Enables support for the PCIe controller in the DRA7xx SoC. There
24 are two instances of PCIe controller in DRA7xx. This controller can
25 work either as EP or RC. In order to enable host-specific features
26 PCI_DRA7XX_HOST must be selected and in order to enable device-
27 specific features PCI_DRA7XX_EP must be selected. This uses
28 the DesignWare core.
29
30if PCI_DRA7XX
31 21
32config PCI_DRA7XX_HOST 22config PCI_DRA7XX_HOST
33 bool "PCI DRA7xx Host Mode" 23 bool "TI DRA7xx PCIe controller Host Mode"
34 depends on PCI 24 depends on SOC_DRA7XX || COMPILE_TEST
35 depends on PCI_MSI_IRQ_DOMAIN 25 depends on PCI && PCI_MSI_IRQ_DOMAIN
26 depends on OF && HAS_IOMEM && TI_PIPE3
36 select PCIE_DW_HOST 27 select PCIE_DW_HOST
28 select PCI_DRA7XX
37 default y 29 default y
38 help 30 help
39 Enables support for the PCIe controller in the DRA7xx SoC to work in 31 Enables support for the PCIe controller in the DRA7xx SoC to work in
40 host mode. 32 host mode. There are two instances of PCIe controller in DRA7xx.
33 This controller can work either as EP or RC. In order to enable
34 host-specific features PCI_DRA7XX_HOST must be selected and in order
35 to enable device-specific features PCI_DRA7XX_EP must be selected.
36 This uses the DesignWare core.
41 37
42config PCI_DRA7XX_EP 38config PCI_DRA7XX_EP
43 bool "PCI DRA7xx Endpoint Mode" 39 bool "TI DRA7xx PCIe controller Endpoint Mode"
40 depends on SOC_DRA7XX || COMPILE_TEST
44 depends on PCI_ENDPOINT 41 depends on PCI_ENDPOINT
42 depends on OF && HAS_IOMEM && TI_PIPE3
45 select PCIE_DW_EP 43 select PCIE_DW_EP
44 select PCI_DRA7XX
46 help 45 help
47 Enables support for the PCIe controller in the DRA7xx SoC to work in 46 Enables support for the PCIe controller in the DRA7xx SoC to work in
48 endpoint mode. 47 endpoint mode. There are two instances of PCIe controller in DRA7xx.
49 48 This controller can work either as EP or RC. In order to enable
50endif 49 host-specific features PCI_DRA7XX_HOST must be selected and in order
50 to enable device-specific features PCI_DRA7XX_EP must be selected.
51 This uses the DesignWare core.
51 52
52config PCIE_DW_PLAT 53config PCIE_DW_PLAT
53 bool "Platform bus based DesignWare PCIe Controller" 54 bool "Platform bus based DesignWare PCIe Controller"
@@ -149,15 +150,28 @@ config PCIE_ARMADA_8K
149 DesignWare core functions to implement the driver. 150 DesignWare core functions to implement the driver.
150 151
151config PCIE_ARTPEC6 152config PCIE_ARTPEC6
152 bool "Axis ARTPEC-6 PCIe controller" 153 bool
153 depends on PCI 154
155config PCIE_ARTPEC6_HOST
156 bool "Axis ARTPEC-6 PCIe controller Host Mode"
154 depends on MACH_ARTPEC6 157 depends on MACH_ARTPEC6
155 depends on PCI_MSI_IRQ_DOMAIN 158 depends on PCI && PCI_MSI_IRQ_DOMAIN
156 select PCIEPORTBUS 159 select PCIEPORTBUS
157 select PCIE_DW_HOST 160 select PCIE_DW_HOST
161 select PCIE_ARTPEC6
162 help
163 Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
164 host mode. This uses the DesignWare core.
165
166config PCIE_ARTPEC6_EP
167 bool "Axis ARTPEC-6 PCIe controller Endpoint Mode"
168 depends on MACH_ARTPEC6
169 depends on PCI_ENDPOINT
170 select PCIE_DW_EP
171 select PCIE_ARTPEC6
158 help 172 help
159 Say Y here to enable PCIe controller support on Axis ARTPEC-6 173 Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
160 SoCs. This PCIe controller uses the DesignWare core. 174 endpoint mode. This uses the DesignWare core.
161 175
162config PCIE_KIRIN 176config PCIE_KIRIN
163 depends on OF && ARM64 177 depends on OF && ARM64
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
index 41ba499c96ee..5d2ce72c7a52 100644
--- a/drivers/pci/dwc/Makefile
+++ b/drivers/pci/dwc/Makefile
@@ -3,9 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
3obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o 3obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
4obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o 4obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
5obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o 5obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
6ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),) 6obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
7 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
8endif
9obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o 7obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
10obj-$(CONFIG_PCI_IMX6) += pci-imx6.o 8obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
11obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o 9obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
@@ -27,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
27# ARM64 and use internal ifdefs to only build the pieces we need 25# ARM64 and use internal ifdefs to only build the pieces we need
28# depending on whether ACPI, the DT driver, or both are enabled. 26# depending on whether ACPI, the DT driver, or both are enabled.
29 27
28ifdef CONFIG_PCI
30obj-$(CONFIG_ARM64) += pcie-hisi.o 29obj-$(CONFIG_ARM64) += pcie-hisi.o
30endif
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index e77a4ceed74c..ed8558d638e5 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -1,13 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs 3 * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs
3 * 4 *
4 * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com 5 * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com
5 * 6 *
6 * Authors: Kishon Vijay Abraham I <kishon@ti.com> 7 * Authors: Kishon Vijay Abraham I <kishon@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */ 8 */
12 9
13#include <linux/delay.h> 10#include <linux/delay.h>
@@ -110,7 +107,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
110 writel(value, pcie->base + offset); 107 writel(value, pcie->base + offset);
111} 108}
112 109
113static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr) 110static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
114{ 111{
115 return pci_addr & DRA7XX_CPU_TO_BUS_ADDR; 112 return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
116} 113}
@@ -226,6 +223,7 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
226 223
227static const struct irq_domain_ops intx_domain_ops = { 224static const struct irq_domain_ops intx_domain_ops = {
228 .map = dra7xx_pcie_intx_map, 225 .map = dra7xx_pcie_intx_map,
226 .xlate = pci_irqd_intx_xlate,
229}; 227};
230 228
231static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) 229static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
@@ -256,7 +254,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
256 struct dra7xx_pcie *dra7xx = arg; 254 struct dra7xx_pcie *dra7xx = arg;
257 struct dw_pcie *pci = dra7xx->pci; 255 struct dw_pcie *pci = dra7xx->pci;
258 struct pcie_port *pp = &pci->pp; 256 struct pcie_port *pp = &pci->pp;
259 u32 reg; 257 unsigned long reg;
258 u32 virq, bit;
260 259
261 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI); 260 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
262 261
@@ -268,8 +267,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
268 case INTB: 267 case INTB:
269 case INTC: 268 case INTC:
270 case INTD: 269 case INTD:
271 generic_handle_irq(irq_find_mapping(dra7xx->irq_domain, 270 for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
272 ffs(reg))); 271 virq = irq_find_mapping(dra7xx->irq_domain, bit);
272 if (virq)
273 generic_handle_irq(virq);
274 }
273 break; 275 break;
274 } 276 }
275 277
@@ -337,15 +339,6 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
337 return IRQ_HANDLED; 339 return IRQ_HANDLED;
338} 340}
339 341
340static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
341{
342 u32 reg;
343
344 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
345 dw_pcie_writel_dbi2(pci, reg, 0x0);
346 dw_pcie_writel_dbi(pci, reg, 0x0);
347}
348
349static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep) 342static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
350{ 343{
351 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 344 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -375,7 +368,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx,
375 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg); 368 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg);
376} 369}
377 370
378static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, 371static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
379 enum pci_epc_irq_type type, u8 interrupt_num) 372 enum pci_epc_irq_type type, u8 interrupt_num)
380{ 373{
381 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 374 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -470,6 +463,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
470 if (!pci->dbi_base) 463 if (!pci->dbi_base)
471 return -ENOMEM; 464 return -ENOMEM;
472 465
466 pp->ops = &dra7xx_pcie_host_ops;
467
473 ret = dw_pcie_host_init(pp); 468 ret = dw_pcie_host_init(pp);
474 if (ret) { 469 if (ret) {
475 dev_err(dev, "failed to initialize host\n"); 470 dev_err(dev, "failed to initialize host\n");
@@ -599,7 +594,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
599 void __iomem *base; 594 void __iomem *base;
600 struct resource *res; 595 struct resource *res;
601 struct dw_pcie *pci; 596 struct dw_pcie *pci;
602 struct pcie_port *pp;
603 struct dra7xx_pcie *dra7xx; 597 struct dra7xx_pcie *dra7xx;
604 struct device *dev = &pdev->dev; 598 struct device *dev = &pdev->dev;
605 struct device_node *np = dev->of_node; 599 struct device_node *np = dev->of_node;
@@ -627,9 +621,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
627 pci->dev = dev; 621 pci->dev = dev;
628 pci->ops = &dw_pcie_ops; 622 pci->ops = &dw_pcie_ops;
629 623
630 pp = &pci->pp;
631 pp->ops = &dra7xx_pcie_host_ops;
632
633 irq = platform_get_irq(pdev, 0); 624 irq = platform_get_irq(pdev, 0);
634 if (irq < 0) { 625 if (irq < 0) {
635 dev_err(dev, "missing IRQ resource: %d\n", irq); 626 dev_err(dev, "missing IRQ resource: %d\n", irq);
@@ -705,6 +696,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
705 696
706 switch (mode) { 697 switch (mode) {
707 case DW_PCIE_RC_TYPE: 698 case DW_PCIE_RC_TYPE:
699 if (!IS_ENABLED(CONFIG_PCI_DRA7XX_HOST)) {
700 ret = -ENODEV;
701 goto err_gpio;
702 }
703
708 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE, 704 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
709 DEVICE_TYPE_RC); 705 DEVICE_TYPE_RC);
710 ret = dra7xx_add_pcie_port(dra7xx, pdev); 706 ret = dra7xx_add_pcie_port(dra7xx, pdev);
@@ -712,6 +708,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
712 goto err_gpio; 708 goto err_gpio;
713 break; 709 break;
714 case DW_PCIE_EP_TYPE: 710 case DW_PCIE_EP_TYPE:
711 if (!IS_ENABLED(CONFIG_PCI_DRA7XX_EP)) {
712 ret = -ENODEV;
713 goto err_gpio;
714 }
715
715 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE, 716 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
716 DEVICE_TYPE_EP); 717 DEVICE_TYPE_EP);
717 718
@@ -810,7 +811,7 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
810} 811}
811#endif 812#endif
812 813
813void dra7xx_pcie_shutdown(struct platform_device *pdev) 814static void dra7xx_pcie_shutdown(struct platform_device *pdev)
814{ 815{
815 struct device *dev = &pdev->dev; 816 struct device *dev = &pdev->dev;
816 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); 817 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
diff --git a/drivers/pci/dwc/pci-exynos.c b/drivers/pci/dwc/pci-exynos.c
index 5596fdedbb94..ca6278113936 100644
--- a/drivers/pci/dwc/pci-exynos.c
+++ b/drivers/pci/dwc/pci-exynos.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for Samsung EXYNOS SoCs 3 * PCIe host controller driver for Samsung EXYNOS SoCs
3 * 4 *
@@ -5,10 +6,6 @@
5 * http://www.samsung.com 6 * http://www.samsung.com
6 * 7 *
7 * Author: Jingoo Han <jg1.han@samsung.com> 8 * Author: Jingoo Han <jg1.han@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */ 9 */
13 10
14#include <linux/clk.h> 11#include <linux/clk.h>
@@ -55,49 +52,8 @@
55#define PCIE_ELBI_SLV_ARMISC 0x120 52#define PCIE_ELBI_SLV_ARMISC 0x120
56#define PCIE_ELBI_SLV_DBI_ENABLE BIT(21) 53#define PCIE_ELBI_SLV_DBI_ENABLE BIT(21)
57 54
58/* PCIe Purple registers */
59#define PCIE_PHY_GLOBAL_RESET 0x000
60#define PCIE_PHY_COMMON_RESET 0x004
61#define PCIE_PHY_CMN_REG 0x008
62#define PCIE_PHY_MAC_RESET 0x00c
63#define PCIE_PHY_PLL_LOCKED 0x010
64#define PCIE_PHY_TRSVREG_RESET 0x020
65#define PCIE_PHY_TRSV_RESET 0x024
66
67/* PCIe PHY registers */
68#define PCIE_PHY_IMPEDANCE 0x004
69#define PCIE_PHY_PLL_DIV_0 0x008
70#define PCIE_PHY_PLL_BIAS 0x00c
71#define PCIE_PHY_DCC_FEEDBACK 0x014
72#define PCIE_PHY_PLL_DIV_1 0x05c
73#define PCIE_PHY_COMMON_POWER 0x064
74#define PCIE_PHY_COMMON_PD_CMN BIT(3)
75#define PCIE_PHY_TRSV0_EMP_LVL 0x084
76#define PCIE_PHY_TRSV0_DRV_LVL 0x088
77#define PCIE_PHY_TRSV0_RXCDR 0x0ac
78#define PCIE_PHY_TRSV0_POWER 0x0c4
79#define PCIE_PHY_TRSV0_PD_TSV BIT(7)
80#define PCIE_PHY_TRSV0_LVCC 0x0dc
81#define PCIE_PHY_TRSV1_EMP_LVL 0x144
82#define PCIE_PHY_TRSV1_RXCDR 0x16c
83#define PCIE_PHY_TRSV1_POWER 0x184
84#define PCIE_PHY_TRSV1_PD_TSV BIT(7)
85#define PCIE_PHY_TRSV1_LVCC 0x19c
86#define PCIE_PHY_TRSV2_EMP_LVL 0x204
87#define PCIE_PHY_TRSV2_RXCDR 0x22c
88#define PCIE_PHY_TRSV2_POWER 0x244
89#define PCIE_PHY_TRSV2_PD_TSV BIT(7)
90#define PCIE_PHY_TRSV2_LVCC 0x25c
91#define PCIE_PHY_TRSV3_EMP_LVL 0x2c4
92#define PCIE_PHY_TRSV3_RXCDR 0x2ec
93#define PCIE_PHY_TRSV3_POWER 0x304
94#define PCIE_PHY_TRSV3_PD_TSV BIT(7)
95#define PCIE_PHY_TRSV3_LVCC 0x31c
96
97struct exynos_pcie_mem_res { 55struct exynos_pcie_mem_res {
98 void __iomem *elbi_base; /* DT 0th resource: PCIe CTRL */ 56 void __iomem *elbi_base; /* DT 0th resource: PCIe CTRL */
99 void __iomem *phy_base; /* DT 1st resource: PHY CTRL */
100 void __iomem *block_base; /* DT 2nd resource: PHY ADDITIONAL CTRL */
101}; 57};
102 58
103struct exynos_pcie_clk_res { 59struct exynos_pcie_clk_res {
@@ -112,8 +68,6 @@ struct exynos_pcie {
112 const struct exynos_pcie_ops *ops; 68 const struct exynos_pcie_ops *ops;
113 int reset_gpio; 69 int reset_gpio;
114 70
115 /* For Generic PHY Framework */
116 bool using_phy;
117 struct phy *phy; 71 struct phy *phy;
118}; 72};
119 73
@@ -141,20 +95,6 @@ static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev,
141 if (IS_ERR(ep->mem_res->elbi_base)) 95 if (IS_ERR(ep->mem_res->elbi_base))
142 return PTR_ERR(ep->mem_res->elbi_base); 96 return PTR_ERR(ep->mem_res->elbi_base);
143 97
144 /* If using the PHY framework, doesn't need to get other resource */
145 if (ep->using_phy)
146 return 0;
147
148 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
149 ep->mem_res->phy_base = devm_ioremap_resource(dev, res);
150 if (IS_ERR(ep->mem_res->phy_base))
151 return PTR_ERR(ep->mem_res->phy_base);
152
153 res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
154 ep->mem_res->block_base = devm_ioremap_resource(dev, res);
155 if (IS_ERR(ep->mem_res->block_base))
156 return PTR_ERR(ep->mem_res->block_base);
157
158 return 0; 98 return 0;
159} 99}
160 100
@@ -279,111 +219,6 @@ static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep)
279 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET); 219 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET);
280 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET); 220 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET);
281 exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET); 221 exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET);
282 exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_MAC_RESET);
283}
284
285static void exynos_pcie_assert_phy_reset(struct exynos_pcie *ep)
286{
287 exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_MAC_RESET);
288 exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_GLOBAL_RESET);
289}
290
291static void exynos_pcie_deassert_phy_reset(struct exynos_pcie *ep)
292{
293 exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_GLOBAL_RESET);
294 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_PWR_RESET);
295 exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET);
296 exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_CMN_REG);
297 exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSVREG_RESET);
298 exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSV_RESET);
299}
300
301static void exynos_pcie_power_on_phy(struct exynos_pcie *ep)
302{
303 u32 val;
304
305 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER);
306 val &= ~PCIE_PHY_COMMON_PD_CMN;
307 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER);
308
309 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER);
310 val &= ~PCIE_PHY_TRSV0_PD_TSV;
311 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER);
312
313 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER);
314 val &= ~PCIE_PHY_TRSV1_PD_TSV;
315 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER);
316
317 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER);
318 val &= ~PCIE_PHY_TRSV2_PD_TSV;
319 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER);
320
321 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER);
322 val &= ~PCIE_PHY_TRSV3_PD_TSV;
323 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER);
324}
325
326static void exynos_pcie_power_off_phy(struct exynos_pcie *ep)
327{
328 u32 val;
329
330 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER);
331 val |= PCIE_PHY_COMMON_PD_CMN;
332 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER);
333
334 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER);
335 val |= PCIE_PHY_TRSV0_PD_TSV;
336 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER);
337
338 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER);
339 val |= PCIE_PHY_TRSV1_PD_TSV;
340 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER);
341
342 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER);
343 val |= PCIE_PHY_TRSV2_PD_TSV;
344 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER);
345
346 val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER);
347 val |= PCIE_PHY_TRSV3_PD_TSV;
348 exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER);
349}
350
351static void exynos_pcie_init_phy(struct exynos_pcie *ep)
352{
353 /* DCC feedback control off */
354 exynos_pcie_writel(ep->mem_res->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK);
355
356 /* set TX/RX impedance */
357 exynos_pcie_writel(ep->mem_res->phy_base, 0xd5, PCIE_PHY_IMPEDANCE);
358
359 /* set 50Mhz PHY clock */
360 exynos_pcie_writel(ep->mem_res->phy_base, 0x14, PCIE_PHY_PLL_DIV_0);
361 exynos_pcie_writel(ep->mem_res->phy_base, 0x12, PCIE_PHY_PLL_DIV_1);
362
363 /* set TX Differential output for lane 0 */
364 exynos_pcie_writel(ep->mem_res->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL);
365
366 /* set TX Pre-emphasis Level Control for lane 0 to minimum */
367 exynos_pcie_writel(ep->mem_res->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL);
368
369 /* set RX clock and data recovery bandwidth */
370 exynos_pcie_writel(ep->mem_res->phy_base, 0xe7, PCIE_PHY_PLL_BIAS);
371 exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR);
372 exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR);
373 exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR);
374 exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR);
375
376 /* change TX Pre-emphasis Level Control for lanes */
377 exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL);
378 exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL);
379 exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL);
380 exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL);
381
382 /* set LVCC */
383 exynos_pcie_writel(ep->mem_res->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC);
384 exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC);
385 exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC);
386 exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC);
387} 222}
388 223
389static void exynos_pcie_assert_reset(struct exynos_pcie *ep) 224static void exynos_pcie_assert_reset(struct exynos_pcie *ep)
@@ -401,7 +236,6 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
401 struct dw_pcie *pci = ep->pci; 236 struct dw_pcie *pci = ep->pci;
402 struct pcie_port *pp = &pci->pp; 237 struct pcie_port *pp = &pci->pp;
403 struct device *dev = pci->dev; 238 struct device *dev = pci->dev;
404 u32 val;
405 239
406 if (dw_pcie_link_up(pci)) { 240 if (dw_pcie_link_up(pci)) {
407 dev_err(dev, "Link already up\n"); 241 dev_err(dev, "Link already up\n");
@@ -410,32 +244,13 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
410 244
411 exynos_pcie_assert_core_reset(ep); 245 exynos_pcie_assert_core_reset(ep);
412 246
413 if (ep->using_phy) { 247 phy_reset(ep->phy);
414 phy_reset(ep->phy);
415
416 exynos_pcie_writel(ep->mem_res->elbi_base, 1,
417 PCIE_PWR_RESET);
418
419 phy_power_on(ep->phy);
420 phy_init(ep->phy);
421 } else {
422 exynos_pcie_assert_phy_reset(ep);
423 exynos_pcie_deassert_phy_reset(ep);
424 exynos_pcie_power_on_phy(ep);
425 exynos_pcie_init_phy(ep);
426
427 /* pulse for common reset */
428 exynos_pcie_writel(ep->mem_res->block_base, 1,
429 PCIE_PHY_COMMON_RESET);
430 udelay(500);
431 exynos_pcie_writel(ep->mem_res->block_base, 0,
432 PCIE_PHY_COMMON_RESET);
433 }
434 248
435 /* pulse for common reset */ 249 exynos_pcie_writel(ep->mem_res->elbi_base, 1,
436 exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_COMMON_RESET); 250 PCIE_PWR_RESET);
437 udelay(500); 251
438 exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET); 252 phy_power_on(ep->phy);
253 phy_init(ep->phy);
439 254
440 exynos_pcie_deassert_core_reset(ep); 255 exynos_pcie_deassert_core_reset(ep);
441 dw_pcie_setup_rc(pp); 256 dw_pcie_setup_rc(pp);
@@ -449,18 +264,7 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
449 if (!dw_pcie_wait_for_link(pci)) 264 if (!dw_pcie_wait_for_link(pci))
450 return 0; 265 return 0;
451 266
452 if (ep->using_phy) { 267 phy_power_off(ep->phy);
453 phy_power_off(ep->phy);
454 return -ETIMEDOUT;
455 }
456
457 while (exynos_pcie_readl(ep->mem_res->phy_base,
458 PCIE_PHY_PLL_LOCKED) == 0) {
459 val = exynos_pcie_readl(ep->mem_res->block_base,
460 PCIE_PHY_PLL_LOCKED);
461 dev_info(dev, "PLL Locked: 0x%x\n", val);
462 }
463 exynos_pcie_power_off_phy(ep);
464 return -ETIMEDOUT; 268 return -ETIMEDOUT;
465} 269}
466 270
@@ -678,16 +482,13 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
678 482
679 ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); 483 ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
680 484
681 /* Assume that controller doesn't use the PHY framework */
682 ep->using_phy = false;
683
684 ep->phy = devm_of_phy_get(dev, np, NULL); 485 ep->phy = devm_of_phy_get(dev, np, NULL);
685 if (IS_ERR(ep->phy)) { 486 if (IS_ERR(ep->phy)) {
686 if (PTR_ERR(ep->phy) == -EPROBE_DEFER) 487 if (PTR_ERR(ep->phy) == -EPROBE_DEFER)
687 return PTR_ERR(ep->phy); 488 return PTR_ERR(ep->phy);
688 dev_warn(dev, "Use the 'phy' property. Current DT of pci-exynos was deprecated!!\n"); 489
689 } else 490 ep->phy = NULL;
690 ep->using_phy = true; 491 }
691 492
692 if (ep->ops && ep->ops->get_mem_resources) { 493 if (ep->ops && ep->ops->get_mem_resources) {
693 ret = ep->ops->get_mem_resources(pdev, ep); 494 ret = ep->ops->get_mem_resources(pdev, ep);
@@ -695,7 +496,8 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
695 return ret; 496 return ret;
696 } 497 }
697 498
698 if (ep->ops && ep->ops->get_clk_resources) { 499 if (ep->ops && ep->ops->get_clk_resources &&
500 ep->ops->init_clk_resources) {
699 ret = ep->ops->get_clk_resources(ep); 501 ret = ep->ops->get_clk_resources(ep);
700 if (ret) 502 if (ret)
701 return ret; 503 return ret;
@@ -713,8 +515,7 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
713 return 0; 515 return 0;
714 516
715fail_probe: 517fail_probe:
716 if (ep->using_phy) 518 phy_exit(ep->phy);
717 phy_exit(ep->phy);
718 519
719 if (ep->ops && ep->ops->deinit_clk_resources) 520 if (ep->ops && ep->ops->deinit_clk_resources)
720 ep->ops->deinit_clk_resources(ep); 521 ep->ops->deinit_clk_resources(ep);
diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
index b73483534a5b..4fddbd08b089 100644
--- a/drivers/pci/dwc/pci-imx6.c
+++ b/drivers/pci/dwc/pci-imx6.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for Freescale i.MX6 SoCs 3 * PCIe host controller driver for Freescale i.MX6 SoCs
3 * 4 *
@@ -5,10 +6,6 @@
5 * http://www.kosagi.com 6 * http://www.kosagi.com
6 * 7 *
7 * Author: Sean Cross <xobs@kosagi.com> 8 * Author: Sean Cross <xobs@kosagi.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */ 9 */
13 10
14#include <linux/clk.h> 11#include <linux/clk.h>
diff --git a/drivers/pci/dwc/pci-keystone-dw.c b/drivers/pci/dwc/pci-keystone-dw.c
index 2fb20b887d2a..99a0e7076221 100644
--- a/drivers/pci/dwc/pci-keystone-dw.c
+++ b/drivers/pci/dwc/pci-keystone-dw.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * DesignWare application register space functions for Keystone PCI controller 3 * DesignWare application register space functions for Keystone PCI controller
3 * 4 *
@@ -5,11 +6,6 @@
5 * http://www.ti.com 6 * http://www.ti.com
6 * 7 *
7 * Author: Murali Karicheri <m-karicheri2@ti.com> 8 * Author: Murali Karicheri <m-karicheri2@ti.com>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */ 9 */
14 10
15#include <linux/irq.h> 11#include <linux/irq.h>
diff --git a/drivers/pci/dwc/pci-keystone.c b/drivers/pci/dwc/pci-keystone.c
index 5bee3af47588..d4f8ab90c018 100644
--- a/drivers/pci/dwc/pci-keystone.c
+++ b/drivers/pci/dwc/pci-keystone.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for Texas Instruments Keystone SoCs 3 * PCIe host controller driver for Texas Instruments Keystone SoCs
3 * 4 *
@@ -6,10 +7,6 @@
6 * 7 *
7 * Author: Murali Karicheri <m-karicheri2@ti.com> 8 * Author: Murali Karicheri <m-karicheri2@ti.com>
8 * Implementation based on pci-exynos.c and pcie-designware.c 9 * Implementation based on pci-exynos.c and pcie-designware.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */ 10 */
14 11
15#include <linux/irqchip/chained_irq.h> 12#include <linux/irqchip/chained_irq.h>
@@ -178,7 +175,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
178 } 175 }
179 176
180 /* interrupt controller is in a child node */ 177 /* interrupt controller is in a child node */
181 *np_temp = of_find_node_by_name(np_pcie, controller); 178 *np_temp = of_get_child_by_name(np_pcie, controller);
182 if (!(*np_temp)) { 179 if (!(*np_temp)) {
183 dev_err(dev, "Node for %s is absent\n", controller); 180 dev_err(dev, "Node for %s is absent\n", controller);
184 return -EINVAL; 181 return -EINVAL;
@@ -187,6 +184,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
187 temp = of_irq_count(*np_temp); 184 temp = of_irq_count(*np_temp);
188 if (!temp) { 185 if (!temp) {
189 dev_err(dev, "No IRQ entries in %s\n", controller); 186 dev_err(dev, "No IRQ entries in %s\n", controller);
187 of_node_put(*np_temp);
190 return -EINVAL; 188 return -EINVAL;
191 } 189 }
192 190
@@ -204,6 +202,8 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
204 break; 202 break;
205 } 203 }
206 204
205 of_node_put(*np_temp);
206
207 if (temp) { 207 if (temp) {
208 *num_irqs = temp; 208 *num_irqs = temp;
209 return 0; 209 return 0;
diff --git a/drivers/pci/dwc/pci-keystone.h b/drivers/pci/dwc/pci-keystone.h
index 30b7bc2ac380..1dd1f3ef98e7 100644
--- a/drivers/pci/dwc/pci-keystone.h
+++ b/drivers/pci/dwc/pci-keystone.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Keystone PCI Controller's common includes 3 * Keystone PCI Controller's common includes
3 * 4 *
@@ -5,11 +6,6 @@
5 * http://www.ti.com 6 * http://www.ti.com
6 * 7 *
7 * Author: Murali Karicheri <m-karicheri2@ti.com> 8 * Author: Murali Karicheri <m-karicheri2@ti.com>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */ 9 */
14 10
15#define MAX_MSI_HOST_IRQS 8 11#define MAX_MSI_HOST_IRQS 8
diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c
index 8f34c2fdc600..a7b4159631ae 100644
--- a/drivers/pci/dwc/pci-layerscape.c
+++ b/drivers/pci/dwc/pci-layerscape.c
@@ -1,13 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for Freescale Layerscape SoCs 3 * PCIe host controller driver for Freescale Layerscape SoCs
3 * 4 *
4 * Copyright (C) 2014 Freescale Semiconductor. 5 * Copyright (C) 2014 Freescale Semiconductor.
5 * 6 *
6 * Author: Minghuan Lian <Minghuan.Lian@freescale.com> 7 * Author: Minghuan Lian <Minghuan.Lian@freescale.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */ 8 */
12 9
13#include <linux/kernel.h> 10#include <linux/kernel.h>
diff --git a/drivers/pci/dwc/pcie-armada8k.c b/drivers/pci/dwc/pcie-armada8k.c
index 370d057c0046..b587352f8b9f 100644
--- a/drivers/pci/dwc/pcie-armada8k.c
+++ b/drivers/pci/dwc/pcie-armada8k.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for Marvell Armada-8K SoCs 3 * PCIe host controller driver for Marvell Armada-8K SoCs
3 * 4 *
@@ -7,10 +8,6 @@
7 * 8 *
8 * Author: Yehuda Yitshak <yehuday@marvell.com> 9 * Author: Yehuda Yitshak <yehuday@marvell.com>
9 * Author: Shadi Ammouri <shadi@marvell.com> 10 * Author: Shadi Ammouri <shadi@marvell.com>
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */ 11 */
15 12
16#include <linux/clk.h> 13#include <linux/clk.h>
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index 6653619db6a1..93b3df9ed1b5 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -1,18 +1,16 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for Axis ARTPEC-6 SoC 3 * PCIe host controller driver for Axis ARTPEC-6 SoC
3 * 4 *
4 * Author: Niklas Cassel <niklas.cassel@axis.com> 5 * Author: Niklas Cassel <niklas.cassel@axis.com>
5 * 6 *
6 * Based on work done by Phil Edworthy <phil@edworthys.org> 7 * Based on work done by Phil Edworthy <phil@edworthys.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */ 8 */
12 9
13#include <linux/delay.h> 10#include <linux/delay.h>
14#include <linux/kernel.h> 11#include <linux/kernel.h>
15#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/of_device.h>
16#include <linux/pci.h> 14#include <linux/pci.h>
17#include <linux/platform_device.h> 15#include <linux/platform_device.h>
18#include <linux/resource.h> 16#include <linux/resource.h>
@@ -26,44 +24,72 @@
26 24
27#define to_artpec6_pcie(x) dev_get_drvdata((x)->dev) 25#define to_artpec6_pcie(x) dev_get_drvdata((x)->dev)
28 26
27enum artpec_pcie_variants {
28 ARTPEC6,
29 ARTPEC7,
30};
31
29struct artpec6_pcie { 32struct artpec6_pcie {
30 struct dw_pcie *pci; 33 struct dw_pcie *pci;
31 struct regmap *regmap; /* DT axis,syscon-pcie */ 34 struct regmap *regmap; /* DT axis,syscon-pcie */
32 void __iomem *phy_base; /* DT phy */ 35 void __iomem *phy_base; /* DT phy */
36 enum artpec_pcie_variants variant;
37 enum dw_pcie_device_mode mode;
33}; 38};
34 39
40struct artpec_pcie_of_data {
41 enum artpec_pcie_variants variant;
42 enum dw_pcie_device_mode mode;
43};
44
45static const struct of_device_id artpec6_pcie_of_match[];
46
35/* PCIe Port Logic registers (memory-mapped) */ 47/* PCIe Port Logic registers (memory-mapped) */
36#define PL_OFFSET 0x700 48#define PL_OFFSET 0x700
37#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
38#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
39 49
40#define MISC_CONTROL_1_OFF (PL_OFFSET + 0x1bc) 50#define ACK_F_ASPM_CTRL_OFF (PL_OFFSET + 0xc)
41#define DBI_RO_WR_EN 1 51#define ACK_N_FTS_MASK GENMASK(15, 8)
52#define ACK_N_FTS(x) (((x) << 8) & ACK_N_FTS_MASK)
53
54#define FAST_TRAINING_SEQ_MASK GENMASK(7, 0)
55#define FAST_TRAINING_SEQ(x) (((x) << 0) & FAST_TRAINING_SEQ_MASK)
42 56
43/* ARTPEC-6 specific registers */ 57/* ARTPEC-6 specific registers */
44#define PCIECFG 0x18 58#define PCIECFG 0x18
45#define PCIECFG_DBG_OEN (1 << 24) 59#define PCIECFG_DBG_OEN BIT(24)
46#define PCIECFG_CORE_RESET_REQ (1 << 21) 60#define PCIECFG_CORE_RESET_REQ BIT(21)
47#define PCIECFG_LTSSM_ENABLE (1 << 20) 61#define PCIECFG_LTSSM_ENABLE BIT(20)
48#define PCIECFG_CLKREQ_B (1 << 11) 62#define PCIECFG_DEVICE_TYPE_MASK GENMASK(19, 16)
49#define PCIECFG_REFCLK_ENABLE (1 << 10) 63#define PCIECFG_CLKREQ_B BIT(11)
50#define PCIECFG_PLL_ENABLE (1 << 9) 64#define PCIECFG_REFCLK_ENABLE BIT(10)
51#define PCIECFG_PCLK_ENABLE (1 << 8) 65#define PCIECFG_PLL_ENABLE BIT(9)
52#define PCIECFG_RISRCREN (1 << 4) 66#define PCIECFG_PCLK_ENABLE BIT(8)
53#define PCIECFG_MODE_TX_DRV_EN (1 << 3) 67#define PCIECFG_RISRCREN BIT(4)
54#define PCIECFG_CISRREN (1 << 2) 68#define PCIECFG_MODE_TX_DRV_EN BIT(3)
55#define PCIECFG_MACRO_ENABLE (1 << 0) 69#define PCIECFG_CISRREN BIT(2)
70#define PCIECFG_MACRO_ENABLE BIT(0)
71/* ARTPEC-7 specific fields */
72#define PCIECFG_REFCLKSEL BIT(23)
73#define PCIECFG_NOC_RESET BIT(3)
74
75#define PCIESTAT 0x1c
76/* ARTPEC-7 specific fields */
77#define PCIESTAT_EXTREFCLK BIT(3)
56 78
57#define NOCCFG 0x40 79#define NOCCFG 0x40
58#define NOCCFG_ENABLE_CLK_PCIE (1 << 4) 80#define NOCCFG_ENABLE_CLK_PCIE BIT(4)
59#define NOCCFG_POWER_PCIE_IDLEACK (1 << 3) 81#define NOCCFG_POWER_PCIE_IDLEACK BIT(3)
60#define NOCCFG_POWER_PCIE_IDLE (1 << 2) 82#define NOCCFG_POWER_PCIE_IDLE BIT(2)
61#define NOCCFG_POWER_PCIE_IDLEREQ (1 << 1) 83#define NOCCFG_POWER_PCIE_IDLEREQ BIT(1)
62 84
63#define PHY_STATUS 0x118 85#define PHY_STATUS 0x118
64#define PHY_COSPLLLOCK (1 << 0) 86#define PHY_COSPLLLOCK BIT(0)
87
88#define PHY_TX_ASIC_OUT 0x4040
89#define PHY_TX_ASIC_OUT_TX_ACK BIT(0)
65 90
66#define ARTPEC6_CPU_TO_BUS_ADDR 0x0fffffff 91#define PHY_RX_ASIC_OUT 0x405c
92#define PHY_RX_ASIC_OUT_ACK BIT(0)
67 93
68static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset) 94static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset)
69{ 95{
@@ -78,22 +104,123 @@ static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u
78 regmap_write(artpec6_pcie->regmap, offset, val); 104 regmap_write(artpec6_pcie->regmap, offset, val);
79} 105}
80 106
81static u64 artpec6_pcie_cpu_addr_fixup(u64 pci_addr) 107static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
82{ 108{
83 return pci_addr & ARTPEC6_CPU_TO_BUS_ADDR; 109 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
110 struct pcie_port *pp = &pci->pp;
111 struct dw_pcie_ep *ep = &pci->ep;
112
113 switch (artpec6_pcie->mode) {
114 case DW_PCIE_RC_TYPE:
115 return pci_addr - pp->cfg0_base;
116 case DW_PCIE_EP_TYPE:
117 return pci_addr - ep->phys_base;
118 default:
119 dev_err(pci->dev, "UNKNOWN device type\n");
120 }
121 return pci_addr;
84} 122}
85 123
86static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie) 124static int artpec6_pcie_establish_link(struct dw_pcie *pci)
87{ 125{
88 struct dw_pcie *pci = artpec6_pcie->pci; 126 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
89 struct pcie_port *pp = &pci->pp; 127 u32 val;
128
129 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
130 val |= PCIECFG_LTSSM_ENABLE;
131 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
132
133 return 0;
134}
135
136static void artpec6_pcie_stop_link(struct dw_pcie *pci)
137{
138 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
90 u32 val; 139 u32 val;
91 unsigned int retries;
92 140
93 /* Hold DW core in reset */
94 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 141 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
95 val |= PCIECFG_CORE_RESET_REQ; 142 val &= ~PCIECFG_LTSSM_ENABLE;
96 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 143 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
144}
145
146static const struct dw_pcie_ops dw_pcie_ops = {
147 .cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
148 .start_link = artpec6_pcie_establish_link,
149 .stop_link = artpec6_pcie_stop_link,
150};
151
152static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie *artpec6_pcie)
153{
154 struct dw_pcie *pci = artpec6_pcie->pci;
155 struct device *dev = pci->dev;
156 u32 val;
157 unsigned int retries;
158
159 retries = 50;
160 do {
161 usleep_range(1000, 2000);
162 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
163 retries--;
164 } while (retries &&
165 (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
166 if (!retries)
167 dev_err(dev, "PCIe clock manager did not leave idle state\n");
168
169 retries = 50;
170 do {
171 usleep_range(1000, 2000);
172 val = readl(artpec6_pcie->phy_base + PHY_STATUS);
173 retries--;
174 } while (retries && !(val & PHY_COSPLLLOCK));
175 if (!retries)
176 dev_err(dev, "PHY PLL did not lock\n");
177}
178
179static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie *artpec6_pcie)
180{
181 struct dw_pcie *pci = artpec6_pcie->pci;
182 struct device *dev = pci->dev;
183 u32 val;
184 u16 phy_status_tx, phy_status_rx;
185 unsigned int retries;
186
187 retries = 50;
188 do {
189 usleep_range(1000, 2000);
190 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
191 retries--;
192 } while (retries &&
193 (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
194 if (!retries)
195 dev_err(dev, "PCIe clock manager did not leave idle state\n");
196
197 retries = 50;
198 do {
199 usleep_range(1000, 2000);
200 phy_status_tx = readw(artpec6_pcie->phy_base + PHY_TX_ASIC_OUT);
201 phy_status_rx = readw(artpec6_pcie->phy_base + PHY_RX_ASIC_OUT);
202 retries--;
203 } while (retries && ((phy_status_tx & PHY_TX_ASIC_OUT_TX_ACK) ||
204 (phy_status_rx & PHY_RX_ASIC_OUT_ACK)));
205 if (!retries)
206 dev_err(dev, "PHY did not enter Pn state\n");
207}
208
209static void artpec6_pcie_wait_for_phy(struct artpec6_pcie *artpec6_pcie)
210{
211 switch (artpec6_pcie->variant) {
212 case ARTPEC6:
213 artpec6_pcie_wait_for_phy_a6(artpec6_pcie);
214 break;
215 case ARTPEC7:
216 artpec6_pcie_wait_for_phy_a7(artpec6_pcie);
217 break;
218 }
219}
220
221static void artpec6_pcie_init_phy_a6(struct artpec6_pcie *artpec6_pcie)
222{
223 u32 val;
97 224
98 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 225 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
99 val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */ 226 val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */
@@ -119,45 +246,110 @@ static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie)
119 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 246 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
120 val &= ~NOCCFG_POWER_PCIE_IDLEREQ; 247 val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
121 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val); 248 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
249}
122 250
123 retries = 50; 251static void artpec6_pcie_init_phy_a7(struct artpec6_pcie *artpec6_pcie)
124 do { 252{
125 usleep_range(1000, 2000); 253 struct dw_pcie *pci = artpec6_pcie->pci;
126 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 254 u32 val;
127 retries--; 255 bool extrefclk;
128 } while (retries &&
129 (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
130 256
131 retries = 50; 257 /* Check if external reference clock is connected */
132 do { 258 val = artpec6_pcie_readl(artpec6_pcie, PCIESTAT);
133 usleep_range(1000, 2000); 259 extrefclk = !!(val & PCIESTAT_EXTREFCLK);
134 val = readl(artpec6_pcie->phy_base + PHY_STATUS); 260 dev_dbg(pci->dev, "Using reference clock: %s\n",
135 retries--; 261 extrefclk ? "external" : "internal");
136 } while (retries && !(val & PHY_COSPLLLOCK));
137 262
138 /* Take DW core out of reset */
139 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 263 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
140 val &= ~PCIECFG_CORE_RESET_REQ; 264 val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */
265 PCIECFG_PCLK_ENABLE;
266 if (extrefclk)
267 val |= PCIECFG_REFCLKSEL;
268 else
269 val &= ~PCIECFG_REFCLKSEL;
141 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 270 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
142 usleep_range(100, 200); 271 usleep_range(10, 20);
143 272
144 /* setup root complex */ 273 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
145 dw_pcie_setup_rc(pp); 274 val |= NOCCFG_ENABLE_CLK_PCIE;
275 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
276 usleep_range(20, 30);
277
278 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
279 val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
280 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
281}
282
283static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie)
284{
285 switch (artpec6_pcie->variant) {
286 case ARTPEC6:
287 artpec6_pcie_init_phy_a6(artpec6_pcie);
288 break;
289 case ARTPEC7:
290 artpec6_pcie_init_phy_a7(artpec6_pcie);
291 break;
292 }
293}
294
295static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie)
296{
297 struct dw_pcie *pci = artpec6_pcie->pci;
298 u32 val;
299
300 if (artpec6_pcie->variant != ARTPEC7)
301 return;
302
303 /*
304 * Increase the N_FTS (Number of Fast Training Sequences)
305 * to be transmitted when transitioning from L0s to L0.
306 */
307 val = dw_pcie_readl_dbi(pci, ACK_F_ASPM_CTRL_OFF);
308 val &= ~ACK_N_FTS_MASK;
309 val |= ACK_N_FTS(180);
310 dw_pcie_writel_dbi(pci, ACK_F_ASPM_CTRL_OFF, val);
311
312 /*
313 * Set the Number of Fast Training Sequences that the core
314 * advertises as its N_FTS during Gen2 or Gen3 link training.
315 */
316 val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
317 val &= ~FAST_TRAINING_SEQ_MASK;
318 val |= FAST_TRAINING_SEQ(180);
319 dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
320}
321
322static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
323{
324 u32 val;
146 325
147 /* assert LTSSM enable */
148 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 326 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
149 val |= PCIECFG_LTSSM_ENABLE; 327 switch (artpec6_pcie->variant) {
328 case ARTPEC6:
329 val |= PCIECFG_CORE_RESET_REQ;
330 break;
331 case ARTPEC7:
332 val &= ~PCIECFG_NOC_RESET;
333 break;
334 }
150 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 335 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
336}
151 337
152 /* check if the link is up or not */ 338static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie *artpec6_pcie)
153 if (!dw_pcie_wait_for_link(pci)) 339{
154 return 0; 340 u32 val;
155
156 dev_dbg(pci->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
157 dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
158 dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
159 341
160 return -ETIMEDOUT; 342 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
343 switch (artpec6_pcie->variant) {
344 case ARTPEC6:
345 val &= ~PCIECFG_CORE_RESET_REQ;
346 break;
347 case ARTPEC7:
348 val |= PCIECFG_NOC_RESET;
349 break;
350 }
351 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
352 usleep_range(100, 200);
161} 353}
162 354
163static void artpec6_pcie_enable_interrupts(struct artpec6_pcie *artpec6_pcie) 355static void artpec6_pcie_enable_interrupts(struct artpec6_pcie *artpec6_pcie)
@@ -174,7 +366,14 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
174 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 366 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
175 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 367 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
176 368
177 artpec6_pcie_establish_link(artpec6_pcie); 369 artpec6_pcie_assert_core_reset(artpec6_pcie);
370 artpec6_pcie_init_phy(artpec6_pcie);
371 artpec6_pcie_deassert_core_reset(artpec6_pcie);
372 artpec6_pcie_wait_for_phy(artpec6_pcie);
373 artpec6_pcie_set_nfts(artpec6_pcie);
374 dw_pcie_setup_rc(pp);
375 artpec6_pcie_establish_link(pci);
376 dw_pcie_wait_for_link(pci);
178 artpec6_pcie_enable_interrupts(artpec6_pcie); 377 artpec6_pcie_enable_interrupts(artpec6_pcie);
179 378
180 return 0; 379 return 0;
@@ -230,10 +429,78 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
230 return 0; 429 return 0;
231} 430}
232 431
233static const struct dw_pcie_ops dw_pcie_ops = { 432static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
234 .cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup, 433{
434 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
435 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
436 enum pci_barno bar;
437
438 artpec6_pcie_assert_core_reset(artpec6_pcie);
439 artpec6_pcie_init_phy(artpec6_pcie);
440 artpec6_pcie_deassert_core_reset(artpec6_pcie);
441 artpec6_pcie_wait_for_phy(artpec6_pcie);
442 artpec6_pcie_set_nfts(artpec6_pcie);
443
444 for (bar = BAR_0; bar <= BAR_5; bar++)
445 dw_pcie_ep_reset_bar(pci, bar);
446}
447
448static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
449 enum pci_epc_irq_type type, u8 interrupt_num)
450{
451 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
452
453 switch (type) {
454 case PCI_EPC_IRQ_LEGACY:
455 dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
456 return -EINVAL;
457 case PCI_EPC_IRQ_MSI:
458 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
459 default:
460 dev_err(pci->dev, "UNKNOWN IRQ type\n");
461 }
462
463 return 0;
464}
465
466static struct dw_pcie_ep_ops pcie_ep_ops = {
467 .ep_init = artpec6_pcie_ep_init,
468 .raise_irq = artpec6_pcie_raise_irq,
235}; 469};
236 470
471static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie,
472 struct platform_device *pdev)
473{
474 int ret;
475 struct dw_pcie_ep *ep;
476 struct resource *res;
477 struct device *dev = &pdev->dev;
478 struct dw_pcie *pci = artpec6_pcie->pci;
479
480 ep = &pci->ep;
481 ep->ops = &pcie_ep_ops;
482
483 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
484 pci->dbi_base2 = devm_ioremap(dev, res->start, resource_size(res));
485 if (!pci->dbi_base2)
486 return -ENOMEM;
487
488 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
489 if (!res)
490 return -EINVAL;
491
492 ep->phys_base = res->start;
493 ep->addr_size = resource_size(res);
494
495 ret = dw_pcie_ep_init(ep);
496 if (ret) {
497 dev_err(dev, "failed to initialize endpoint\n");
498 return ret;
499 }
500
501 return 0;
502}
503
237static int artpec6_pcie_probe(struct platform_device *pdev) 504static int artpec6_pcie_probe(struct platform_device *pdev)
238{ 505{
239 struct device *dev = &pdev->dev; 506 struct device *dev = &pdev->dev;
@@ -242,6 +509,18 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
242 struct resource *dbi_base; 509 struct resource *dbi_base;
243 struct resource *phy_base; 510 struct resource *phy_base;
244 int ret; 511 int ret;
512 const struct of_device_id *match;
513 const struct artpec_pcie_of_data *data;
514 enum artpec_pcie_variants variant;
515 enum dw_pcie_device_mode mode;
516
517 match = of_match_device(artpec6_pcie_of_match, dev);
518 if (!match)
519 return -EINVAL;
520
521 data = (struct artpec_pcie_of_data *)match->data;
522 variant = (enum artpec_pcie_variants)data->variant;
523 mode = (enum dw_pcie_device_mode)data->mode;
245 524
246 artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL); 525 artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL);
247 if (!artpec6_pcie) 526 if (!artpec6_pcie)
@@ -255,6 +534,8 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
255 pci->ops = &dw_pcie_ops; 534 pci->ops = &dw_pcie_ops;
256 535
257 artpec6_pcie->pci = pci; 536 artpec6_pcie->pci = pci;
537 artpec6_pcie->variant = variant;
538 artpec6_pcie->mode = mode;
258 539
259 dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); 540 dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
260 pci->dbi_base = devm_ioremap_resource(dev, dbi_base); 541 pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
@@ -274,15 +555,73 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
274 555
275 platform_set_drvdata(pdev, artpec6_pcie); 556 platform_set_drvdata(pdev, artpec6_pcie);
276 557
277 ret = artpec6_add_pcie_port(artpec6_pcie, pdev); 558 switch (artpec6_pcie->mode) {
278 if (ret < 0) 559 case DW_PCIE_RC_TYPE:
279 return ret; 560 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))
561 return -ENODEV;
562
563 ret = artpec6_add_pcie_port(artpec6_pcie, pdev);
564 if (ret < 0)
565 return ret;
566 break;
567 case DW_PCIE_EP_TYPE: {
568 u32 val;
569
570 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP))
571 return -ENODEV;
572
573 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
574 val &= ~PCIECFG_DEVICE_TYPE_MASK;
575 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
576 ret = artpec6_add_pcie_ep(artpec6_pcie, pdev);
577 if (ret < 0)
578 return ret;
579 break;
580 }
581 default:
582 dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode);
583 }
280 584
281 return 0; 585 return 0;
282} 586}
283 587
588static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = {
589 .variant = ARTPEC6,
590 .mode = DW_PCIE_RC_TYPE,
591};
592
593static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = {
594 .variant = ARTPEC6,
595 .mode = DW_PCIE_EP_TYPE,
596};
597
598static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = {
599 .variant = ARTPEC7,
600 .mode = DW_PCIE_RC_TYPE,
601};
602
603static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = {
604 .variant = ARTPEC7,
605 .mode = DW_PCIE_EP_TYPE,
606};
607
284static const struct of_device_id artpec6_pcie_of_match[] = { 608static const struct of_device_id artpec6_pcie_of_match[] = {
285 { .compatible = "axis,artpec6-pcie", }, 609 {
610 .compatible = "axis,artpec6-pcie",
611 .data = &artpec6_pcie_rc_of_data,
612 },
613 {
614 .compatible = "axis,artpec6-pcie-ep",
615 .data = &artpec6_pcie_ep_of_data,
616 },
617 {
618 .compatible = "axis,artpec7-pcie",
619 .data = &artpec7_pcie_rc_of_data,
620 },
621 {
622 .compatible = "axis,artpec7-pcie-ep",
623 .data = &artpec7_pcie_ep_of_data,
624 },
286 {}, 625 {},
287}; 626};
288 627
diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c
index d53d5f168363..3a6feeff5f5b 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -1,20 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/** 2/**
2 * Synopsys DesignWare PCIe Endpoint controller driver 3 * Synopsys DesignWare PCIe Endpoint controller driver
3 * 4 *
4 * Copyright (C) 2017 Texas Instruments 5 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com> 6 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 7 */
19 8
20#include <linux/of.h> 9#include <linux/of.h>
@@ -30,21 +19,24 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
30 pci_epc_linkup(epc); 19 pci_epc_linkup(epc);
31} 20}
32 21
33static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) 22void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
34{ 23{
35 u32 reg; 24 u32 reg;
36 25
37 reg = PCI_BASE_ADDRESS_0 + (4 * bar); 26 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
27 dw_pcie_dbi_ro_wr_en(pci);
38 dw_pcie_writel_dbi2(pci, reg, 0x0); 28 dw_pcie_writel_dbi2(pci, reg, 0x0);
39 dw_pcie_writel_dbi(pci, reg, 0x0); 29 dw_pcie_writel_dbi(pci, reg, 0x0);
30 dw_pcie_dbi_ro_wr_dis(pci);
40} 31}
41 32
42static int dw_pcie_ep_write_header(struct pci_epc *epc, 33static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
43 struct pci_epf_header *hdr) 34 struct pci_epf_header *hdr)
44{ 35{
45 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 36 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
46 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 37 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
47 38
39 dw_pcie_dbi_ro_wr_en(pci);
48 dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid); 40 dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid);
49 dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid); 41 dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid);
50 dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid); 42 dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid);
@@ -58,6 +50,7 @@ static int dw_pcie_ep_write_header(struct pci_epc *epc,
58 dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id); 50 dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id);
59 dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN, 51 dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN,
60 hdr->interrupt_pin); 52 hdr->interrupt_pin);
53 dw_pcie_dbi_ro_wr_dis(pci);
61 54
62 return 0; 55 return 0;
63} 56}
@@ -70,8 +63,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
70 u32 free_win; 63 u32 free_win;
71 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 64 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
72 65
73 free_win = find_first_zero_bit(&ep->ib_window_map, 66 free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
74 sizeof(ep->ib_window_map));
75 if (free_win >= ep->num_ib_windows) { 67 if (free_win >= ep->num_ib_windows) {
76 dev_err(pci->dev, "no free inbound window\n"); 68 dev_err(pci->dev, "no free inbound window\n");
77 return -EINVAL; 69 return -EINVAL;
@@ -85,7 +77,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
85 } 77 }
86 78
87 ep->bar_to_atu[bar] = free_win; 79 ep->bar_to_atu[bar] = free_win;
88 set_bit(free_win, &ep->ib_window_map); 80 set_bit(free_win, ep->ib_window_map);
89 81
90 return 0; 82 return 0;
91} 83}
@@ -96,8 +88,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
96 u32 free_win; 88 u32 free_win;
97 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 89 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
98 90
99 free_win = find_first_zero_bit(&ep->ob_window_map, 91 free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows);
100 sizeof(ep->ob_window_map));
101 if (free_win >= ep->num_ob_windows) { 92 if (free_win >= ep->num_ob_windows) {
102 dev_err(pci->dev, "no free outbound window\n"); 93 dev_err(pci->dev, "no free outbound window\n");
103 return -EINVAL; 94 return -EINVAL;
@@ -106,13 +97,14 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
106 dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM, 97 dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
107 phys_addr, pci_addr, size); 98 phys_addr, pci_addr, size);
108 99
109 set_bit(free_win, &ep->ob_window_map); 100 set_bit(free_win, ep->ob_window_map);
110 ep->outbound_addr[free_win] = phys_addr; 101 ep->outbound_addr[free_win] = phys_addr;
111 102
112 return 0; 103 return 0;
113} 104}
114 105
115static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) 106static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
107 enum pci_barno bar)
116{ 108{
117 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 109 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
118 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 110 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -121,10 +113,11 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar)
121 dw_pcie_ep_reset_bar(pci, bar); 113 dw_pcie_ep_reset_bar(pci, bar);
122 114
123 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND); 115 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
124 clear_bit(atu_index, &ep->ib_window_map); 116 clear_bit(atu_index, ep->ib_window_map);
125} 117}
126 118
127static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, 119static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
120 enum pci_barno bar,
128 dma_addr_t bar_phys, size_t size, int flags) 121 dma_addr_t bar_phys, size_t size, int flags)
129{ 122{
130 int ret; 123 int ret;
@@ -142,8 +135,10 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar,
142 if (ret) 135 if (ret)
143 return ret; 136 return ret;
144 137
138 dw_pcie_dbi_ro_wr_en(pci);
145 dw_pcie_writel_dbi2(pci, reg, size - 1); 139 dw_pcie_writel_dbi2(pci, reg, size - 1);
146 dw_pcie_writel_dbi(pci, reg, flags); 140 dw_pcie_writel_dbi(pci, reg, flags);
141 dw_pcie_dbi_ro_wr_dis(pci);
147 142
148 return 0; 143 return 0;
149} 144}
@@ -163,7 +158,8 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
163 return -EINVAL; 158 return -EINVAL;
164} 159}
165 160
166static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) 161static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
162 phys_addr_t addr)
167{ 163{
168 int ret; 164 int ret;
169 u32 atu_index; 165 u32 atu_index;
@@ -175,10 +171,11 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr)
175 return; 171 return;
176 172
177 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND); 173 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND);
178 clear_bit(atu_index, &ep->ob_window_map); 174 clear_bit(atu_index, ep->ob_window_map);
179} 175}
180 176
181static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, 177static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
178 phys_addr_t addr,
182 u64 pci_addr, size_t size) 179 u64 pci_addr, size_t size)
183{ 180{
184 int ret; 181 int ret;
@@ -194,39 +191,37 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr,
194 return 0; 191 return 0;
195} 192}
196 193
197static int dw_pcie_ep_get_msi(struct pci_epc *epc) 194static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
198{ 195{
199 int val; 196 int val;
200 u32 lower_addr;
201 u32 upper_addr;
202 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 197 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
203 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 198 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
204 199
205 val = dw_pcie_readb_dbi(pci, MSI_MESSAGE_CONTROL); 200 val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
206 val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT; 201 if (!(val & MSI_CAP_MSI_EN_MASK))
207
208 lower_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
209 upper_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
210
211 if (!(lower_addr || upper_addr))
212 return -EINVAL; 202 return -EINVAL;
213 203
204 val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
214 return val; 205 return val;
215} 206}
216 207
217static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) 208static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
218{ 209{
219 int val; 210 int val;
220 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 211 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
221 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 212 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
222 213
223 val = (encode_int << MSI_CAP_MMC_SHIFT); 214 val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
215 val &= ~MSI_CAP_MMC_MASK;
216 val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK;
217 dw_pcie_dbi_ro_wr_en(pci);
224 dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val); 218 dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
219 dw_pcie_dbi_ro_wr_dis(pci);
225 220
226 return 0; 221 return 0;
227} 222}
228 223
229static int dw_pcie_ep_raise_irq(struct pci_epc *epc, 224static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
230 enum pci_epc_irq_type type, u8 interrupt_num) 225 enum pci_epc_irq_type type, u8 interrupt_num)
231{ 226{
232 struct dw_pcie_ep *ep = epc_get_drvdata(epc); 227 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -234,7 +229,7 @@ static int dw_pcie_ep_raise_irq(struct pci_epc *epc,
234 if (!ep->ops->raise_irq) 229 if (!ep->ops->raise_irq)
235 return -EINVAL; 230 return -EINVAL;
236 231
237 return ep->ops->raise_irq(ep, type, interrupt_num); 232 return ep->ops->raise_irq(ep, func_no, type, interrupt_num);
238} 233}
239 234
240static void dw_pcie_ep_stop(struct pci_epc *epc) 235static void dw_pcie_ep_stop(struct pci_epc *epc)
@@ -272,10 +267,48 @@ static const struct pci_epc_ops epc_ops = {
272 .stop = dw_pcie_ep_stop, 267 .stop = dw_pcie_ep_stop,
273}; 268};
274 269
270int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
271 u8 interrupt_num)
272{
273 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
274 struct pci_epc *epc = ep->epc;
275 u16 msg_ctrl, msg_data;
276 u32 msg_addr_lower, msg_addr_upper;
277 u64 msg_addr;
278 bool has_upper;
279 int ret;
280
281 /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
282 msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
283 has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
284 msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
285 if (has_upper) {
286 msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
287 msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64);
288 } else {
289 msg_addr_upper = 0;
290 msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32);
291 }
292 msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
293 ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
294 epc->mem->page_size);
295 if (ret)
296 return ret;
297
298 writel(msg_data | (interrupt_num - 1), ep->msi_mem);
299
300 dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
301
302 return 0;
303}
304
275void dw_pcie_ep_exit(struct dw_pcie_ep *ep) 305void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
276{ 306{
277 struct pci_epc *epc = ep->epc; 307 struct pci_epc *epc = ep->epc;
278 308
309 pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
310 epc->mem->page_size);
311
279 pci_epc_mem_exit(epc); 312 pci_epc_mem_exit(epc);
280} 313}
281 314
@@ -298,12 +331,32 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
298 dev_err(dev, "unable to read *num-ib-windows* property\n"); 331 dev_err(dev, "unable to read *num-ib-windows* property\n");
299 return ret; 332 return ret;
300 } 333 }
334 if (ep->num_ib_windows > MAX_IATU_IN) {
335 dev_err(dev, "invalid *num-ib-windows*\n");
336 return -EINVAL;
337 }
301 338
302 ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows); 339 ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows);
303 if (ret < 0) { 340 if (ret < 0) {
304 dev_err(dev, "unable to read *num-ob-windows* property\n"); 341 dev_err(dev, "unable to read *num-ob-windows* property\n");
305 return ret; 342 return ret;
306 } 343 }
344 if (ep->num_ob_windows > MAX_IATU_OUT) {
345 dev_err(dev, "invalid *num-ob-windows*\n");
346 return -EINVAL;
347 }
348
349 ep->ib_window_map = devm_kzalloc(dev, sizeof(long) *
350 BITS_TO_LONGS(ep->num_ib_windows),
351 GFP_KERNEL);
352 if (!ep->ib_window_map)
353 return -ENOMEM;
354
355 ep->ob_window_map = devm_kzalloc(dev, sizeof(long) *
356 BITS_TO_LONGS(ep->num_ob_windows),
357 GFP_KERNEL);
358 if (!ep->ob_window_map)
359 return -ENOMEM;
307 360
308 addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows, 361 addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows,
309 GFP_KERNEL); 362 GFP_KERNEL);
@@ -331,6 +384,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
331 return ret; 384 return ret;
332 } 385 }
333 386
387 ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
388 epc->mem->page_size);
389 if (!ep->msi_mem) {
390 dev_err(dev, "Failed to reserve memory for MSI\n");
391 return -ENOMEM;
392 }
393
334 ep->epc = epc; 394 ep->epc = epc;
335 epc_set_drvdata(epc, ep); 395 epc_set_drvdata(epc, ep);
336 dw_pcie_setup(pci); 396 dw_pcie_setup(pci);
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
index 81e2157a7cfb..8de2d5c69b1d 100644
--- a/drivers/pci/dwc/pcie-designware-host.c
+++ b/drivers/pci/dwc/pcie-designware-host.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Synopsys DesignWare PCIe host controller driver 3 * Synopsys DesignWare PCIe host controller driver
3 * 4 *
@@ -5,10 +6,6 @@
5 * http://www.samsung.com 6 * http://www.samsung.com
6 * 7 *
7 * Author: Jingoo Han <jg1.han@samsung.com> 8 * Author: Jingoo Han <jg1.han@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */ 9 */
13 10
14#include <linux/irqdomain.h> 11#include <linux/irqdomain.h>
@@ -83,10 +80,19 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
83 80
84void dw_pcie_msi_init(struct pcie_port *pp) 81void dw_pcie_msi_init(struct pcie_port *pp)
85{ 82{
83 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
84 struct device *dev = pci->dev;
85 struct page *page;
86 u64 msi_target; 86 u64 msi_target;
87 87
88 pp->msi_data = __get_free_pages(GFP_KERNEL, 0); 88 page = alloc_page(GFP_KERNEL);
89 msi_target = virt_to_phys((void *)pp->msi_data); 89 pp->msi_data = dma_map_page(dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE);
90 if (dma_mapping_error(dev, pp->msi_data)) {
91 dev_err(dev, "failed to map MSI data\n");
92 __free_page(page);
93 return;
94 }
95 msi_target = (u64)pp->msi_data;
90 96
91 /* program the msi_data */ 97 /* program the msi_data */
92 dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4, 98 dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
@@ -187,7 +193,7 @@ static void dw_msi_setup_msg(struct pcie_port *pp, unsigned int irq, u32 pos)
187 if (pp->ops->get_msi_addr) 193 if (pp->ops->get_msi_addr)
188 msi_target = pp->ops->get_msi_addr(pp); 194 msi_target = pp->ops->get_msi_addr(pp);
189 else 195 else
190 msi_target = virt_to_phys((void *)pp->msi_data); 196 msi_target = (u64)pp->msi_data;
191 197
192 msg.address_lo = (u32)(msi_target & 0xffffffff); 198 msg.address_lo = (u32)(msi_target & 0xffffffff);
193 msg.address_hi = (u32)(msi_target >> 32 & 0xffffffff); 199 msg.address_hi = (u32)(msi_target >> 32 & 0xffffffff);
diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c
index 168e2380f493..ebdf28bcd67d 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -1,13 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe RC driver for Synopsys DesignWare Core 3 * PCIe RC driver for Synopsys DesignWare Core
3 * 4 *
4 * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) 5 * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
5 * 6 *
6 * Authors: Joao Pinto <Joao.Pinto@synopsys.com> 7 * Authors: Joao Pinto <Joao.Pinto@synopsys.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */ 8 */
12#include <linux/clk.h> 9#include <linux/clk.h>
13#include <linux/delay.h> 10#include <linux/delay.h>
diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
index 88abdddee2ad..1b7282e5b494 100644
--- a/drivers/pci/dwc/pcie-designware.c
+++ b/drivers/pci/dwc/pcie-designware.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Synopsys DesignWare PCIe host controller driver 3 * Synopsys DesignWare PCIe host controller driver
3 * 4 *
@@ -5,10 +6,6 @@
5 * http://www.samsung.com 6 * http://www.samsung.com
6 * 7 *
7 * Author: Jingoo Han <jg1.han@samsung.com> 8 * Author: Jingoo Han <jg1.han@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */ 9 */
13 10
14#include <linux/delay.h> 11#include <linux/delay.h>
@@ -149,7 +146,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
149 u32 retries, val; 146 u32 retries, val;
150 147
151 if (pci->ops->cpu_addr_fixup) 148 if (pci->ops->cpu_addr_fixup)
152 cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr); 149 cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
153 150
154 if (pci->iatu_unroll_enabled) { 151 if (pci->iatu_unroll_enabled) {
155 dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr, 152 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 e5d9d77b778e..11b13864a406 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Synopsys DesignWare PCIe host controller driver 3 * Synopsys DesignWare PCIe host controller driver
3 * 4 *
@@ -5,15 +6,12 @@
5 * http://www.samsung.com 6 * http://www.samsung.com
6 * 7 *
7 * Author: Jingoo Han <jg1.han@samsung.com> 8 * Author: Jingoo Han <jg1.han@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */ 9 */
13 10
14#ifndef _PCIE_DESIGNWARE_H 11#ifndef _PCIE_DESIGNWARE_H
15#define _PCIE_DESIGNWARE_H 12#define _PCIE_DESIGNWARE_H
16 13
14#include <linux/dma-mapping.h>
17#include <linux/irq.h> 15#include <linux/irq.h>
18#include <linux/msi.h> 16#include <linux/msi.h>
19#include <linux/pci.h> 17#include <linux/pci.h>
@@ -100,10 +98,14 @@
100 98
101#define MSI_MESSAGE_CONTROL 0x52 99#define MSI_MESSAGE_CONTROL 0x52
102#define MSI_CAP_MMC_SHIFT 1 100#define MSI_CAP_MMC_SHIFT 1
101#define MSI_CAP_MMC_MASK (7 << MSI_CAP_MMC_SHIFT)
103#define MSI_CAP_MME_SHIFT 4 102#define MSI_CAP_MME_SHIFT 4
103#define MSI_CAP_MSI_EN_MASK 0x1
104#define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT) 104#define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT)
105#define MSI_MESSAGE_ADDR_L32 0x54 105#define MSI_MESSAGE_ADDR_L32 0x54
106#define MSI_MESSAGE_ADDR_U32 0x58 106#define MSI_MESSAGE_ADDR_U32 0x58
107#define MSI_MESSAGE_DATA_32 0x58
108#define MSI_MESSAGE_DATA_64 0x5C
107 109
108/* 110/*
109 * Maximum number of MSI IRQs can be 256 per controller. But keep 111 * Maximum number of MSI IRQs can be 256 per controller. But keep
@@ -113,6 +115,10 @@
113#define MAX_MSI_IRQS 32 115#define MAX_MSI_IRQS 32
114#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) 116#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
115 117
118/* Maximum number of inbound/outbound iATUs */
119#define MAX_IATU_IN 256
120#define MAX_IATU_OUT 256
121
116struct pcie_port; 122struct pcie_port;
117struct dw_pcie; 123struct dw_pcie;
118struct dw_pcie_ep; 124struct dw_pcie_ep;
@@ -168,7 +174,7 @@ struct pcie_port {
168 const struct dw_pcie_host_ops *ops; 174 const struct dw_pcie_host_ops *ops;
169 int msi_irq; 175 int msi_irq;
170 struct irq_domain *irq_domain; 176 struct irq_domain *irq_domain;
171 unsigned long msi_data; 177 dma_addr_t msi_data;
172 DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); 178 DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
173}; 179};
174 180
@@ -180,8 +186,8 @@ enum dw_pcie_as_type {
180 186
181struct dw_pcie_ep_ops { 187struct dw_pcie_ep_ops {
182 void (*ep_init)(struct dw_pcie_ep *ep); 188 void (*ep_init)(struct dw_pcie_ep *ep);
183 int (*raise_irq)(struct dw_pcie_ep *ep, enum pci_epc_irq_type type, 189 int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
184 u8 interrupt_num); 190 enum pci_epc_irq_type type, u8 interrupt_num);
185}; 191};
186 192
187struct dw_pcie_ep { 193struct dw_pcie_ep {
@@ -192,14 +198,16 @@ struct dw_pcie_ep {
192 size_t page_size; 198 size_t page_size;
193 u8 bar_to_atu[6]; 199 u8 bar_to_atu[6];
194 phys_addr_t *outbound_addr; 200 phys_addr_t *outbound_addr;
195 unsigned long ib_window_map; 201 unsigned long *ib_window_map;
196 unsigned long ob_window_map; 202 unsigned long *ob_window_map;
197 u32 num_ib_windows; 203 u32 num_ib_windows;
198 u32 num_ob_windows; 204 u32 num_ob_windows;
205 void __iomem *msi_mem;
206 phys_addr_t msi_mem_phys;
199}; 207};
200 208
201struct dw_pcie_ops { 209struct dw_pcie_ops {
202 u64 (*cpu_addr_fixup)(u64 cpu_addr); 210 u64 (*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr);
203 u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, 211 u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
204 size_t size); 212 size_t size);
205 void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, 213 void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
@@ -334,6 +342,9 @@ static inline int dw_pcie_host_init(struct pcie_port *pp)
334void dw_pcie_ep_linkup(struct dw_pcie_ep *ep); 342void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
335int dw_pcie_ep_init(struct dw_pcie_ep *ep); 343int dw_pcie_ep_init(struct dw_pcie_ep *ep);
336void dw_pcie_ep_exit(struct dw_pcie_ep *ep); 344void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
345int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
346 u8 interrupt_num);
347void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar);
337#else 348#else
338static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) 349static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
339{ 350{
@@ -347,5 +358,15 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
347static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep) 358static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
348{ 359{
349} 360}
361
362static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
363 u8 interrupt_num)
364{
365 return 0;
366}
367
368static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
369{
370}
350#endif 371#endif
351#endif /* _PCIE_DESIGNWARE_H */ 372#endif /* _PCIE_DESIGNWARE_H */
diff --git a/drivers/pci/dwc/pcie-hisi.c b/drivers/pci/dwc/pcie-hisi.c
index a20179169e06..2658aaebb993 100644
--- a/drivers/pci/dwc/pcie-hisi.c
+++ b/drivers/pci/dwc/pcie-hisi.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for HiSilicon SoCs 3 * PCIe host controller driver for HiSilicon SoCs
3 * 4 *
@@ -6,10 +7,6 @@
6 * Authors: Zhou Wang <wangzhou1@hisilicon.com> 7 * Authors: Zhou Wang <wangzhou1@hisilicon.com>
7 * Dacai Zhu <zhudacai@hisilicon.com> 8 * Dacai Zhu <zhudacai@hisilicon.com>
8 * Gabriele Paoloni <gabriele.paoloni@huawei.com> 9 * Gabriele Paoloni <gabriele.paoloni@huawei.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */ 10 */
14#include <linux/interrupt.h> 11#include <linux/interrupt.h>
15#include <linux/init.h> 12#include <linux/init.h>
diff --git a/drivers/pci/dwc/pcie-histb.c b/drivers/pci/dwc/pcie-histb.c
index 33b01b734d7d..70b5c0b108bf 100644
--- a/drivers/pci/dwc/pcie-histb.c
+++ b/drivers/pci/dwc/pcie-histb.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for HiSilicon STB SoCs 3 * PCIe host controller driver for HiSilicon STB SoCs
3 * 4 *
@@ -5,10 +6,6 @@
5 * 6 *
6 * Authors: Ruqiang Ju <juruqiang@hisilicon.com> 7 * Authors: Ruqiang Ju <juruqiang@hisilicon.com>
7 * Jianguo Sun <sunjianguo1@huawei.com> 8 * Jianguo Sun <sunjianguo1@huawei.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */ 9 */
13 10
14#include <linux/clk.h> 11#include <linux/clk.h>
diff --git a/drivers/pci/dwc/pcie-kirin.c b/drivers/pci/dwc/pcie-kirin.c
index dc3033cf3c19..13d839bd6160 100644
--- a/drivers/pci/dwc/pcie-kirin.c
+++ b/drivers/pci/dwc/pcie-kirin.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for Kirin Phone SoCs 3 * PCIe host controller driver for Kirin Phone SoCs
3 * 4 *
@@ -5,10 +6,6 @@
5 * http://www.huawei.com 6 * http://www.huawei.com
6 * 7 *
7 * Author: Xiaowei Song <songxiaowei@huawei.com> 8 * Author: Xiaowei Song <songxiaowei@huawei.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */ 9 */
13 10
14#include <asm/compiler.h> 11#include <asm/compiler.h>
diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c
index ce7ba5b7552a..6310c66e265c 100644
--- a/drivers/pci/dwc/pcie-qcom.c
+++ b/drivers/pci/dwc/pcie-qcom.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Qualcomm PCIe root complex driver 3 * Qualcomm PCIe root complex driver
3 * 4 *
@@ -5,15 +6,6 @@
5 * Copyright 2015 Linaro Limited. 6 * Copyright 2015 Linaro Limited.
6 * 7 *
7 * Author: Stanimir Varbanov <svarbanov@mm-sol.com> 8 * Author: Stanimir Varbanov <svarbanov@mm-sol.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 and
11 * only version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */ 9 */
18 10
19#include <linux/clk.h> 11#include <linux/clk.h>
@@ -171,7 +163,7 @@ struct qcom_pcie {
171 union qcom_pcie_resources res; 163 union qcom_pcie_resources res;
172 struct phy *phy; 164 struct phy *phy;
173 struct gpio_desc *reset; 165 struct gpio_desc *reset;
174 struct qcom_pcie_ops *ops; 166 const struct qcom_pcie_ops *ops;
175}; 167};
176 168
177#define to_qcom_pcie(x) dev_get_drvdata((x)->dev) 169#define to_qcom_pcie(x) dev_get_drvdata((x)->dev)
@@ -1234,7 +1226,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
1234 1226
1235 pcie->pci = pci; 1227 pcie->pci = pci;
1236 1228
1237 pcie->ops = (struct qcom_pcie_ops *)of_device_get_match_data(dev); 1229 pcie->ops = of_device_get_match_data(dev);
1238 1230
1239 pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW); 1231 pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
1240 if (IS_ERR(pcie->reset)) 1232 if (IS_ERR(pcie->reset))
diff --git a/drivers/pci/dwc/pcie-spear13xx.c b/drivers/pci/dwc/pcie-spear13xx.c
index 709189d23b31..ecb58f7b7566 100644
--- a/drivers/pci/dwc/pcie-spear13xx.c
+++ b/drivers/pci/dwc/pcie-spear13xx.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * PCIe host controller driver for ST Microelectronics SPEAr13xx SoCs 3 * PCIe host controller driver for ST Microelectronics SPEAr13xx SoCs
3 * 4 *
@@ -6,10 +7,6 @@
6 * Copyright (C) 2010-2014 ST Microelectronics 7 * Copyright (C) 2010-2014 ST Microelectronics
7 * Pratyush Anand <pratyush.anand@gmail.com> 8 * Pratyush Anand <pratyush.anand@gmail.com>
8 * Mohit Kumar <mohit.kumar.dhaka@gmail.com> 9 * Mohit Kumar <mohit.kumar.dhaka@gmail.com>
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 */ 10 */
14 11
15#include <linux/clk.h> 12#include <linux/clk.h>