aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 20:57:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 20:57:34 -0500
commit926b02d3eb547daa1d56cf9b586f31b270488b77 (patch)
tree839c5f5ac6ab4f3c50056360da1b8d1af181d6b1 /drivers/pci/controller/dwc
parentcf26057a9441173ad552e90cea3344607075c9ad (diff)
parent72199051af6205049e96ee7ed34f4fc5f44d1baf (diff)
Merge tag 'pci-v4.21-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas: - Remove unused lists from ASPM pcie_link_state (Frederick Lawler) - Fix Broadcom CNB20LE host bridge unintended sign extension (Colin Ian King) - Expand Kconfig "PF" acronyms (Randy Dunlap) - Update MAINTAINERS for arch/x86/kernel/early-quirks.c (Bjorn Helgaas) - Add missing include to drivers/pci.h (Alexandru Gagniuc) - Override Synopsys USB 3.x HAPS device class so dwc3-haps can claim it instead of xhci (Thinh Nguyen) - Clean up P2PDMA documentation (Randy Dunlap) - Allow runtime PM even if driver doesn't supply callbacks (Jarkko Nikula) - Remove status check after submitting Switchtec MRPC Firmware Download commands to avoid Completion Timeouts (Kelvin Cao) - Set Switchtec coherent DMA mask to allow 64-bit DMA (Boris Glimcher) - Fix Switchtec SWITCHTEC_IOCTL_EVENT_IDX_ALL flag overwrite issue (Joey Zhang) - Enable write combining for Switchtec MRPC Input buffers (Kelvin Cao) - Add Switchtec MRPC DMA mode support (Wesley Sheng) - Skip VF scanning on powerpc, which does this in firmware (Sebastian Ott) - Add Amlogic Meson PCIe controller driver and DT bindings (Yue Wang) - Constify histb dw_pcie_host_ops structure (Julia Lawall) - Support multiple power domains for imx6 (Leonard Crestez) - Constify layerscape driver data (Stefan Agner) - Update imx6 Kconfig to allow imx6 PCIe in imx7 kernel (Trent Piepho) - Support armada8k GPIO reset (Baruch Siach) - Support suspend/resume support on imx6 (Leonard Crestez) - Don't hard-code DesignWare DBI/ATU offst (Stephen Warren) - Skip i.MX6 PHY setup on i.MX7D (Andrey Smirnov) - Remove Jianguo Sun from HiSilicon STB maintainers (Lorenzo Pieralisi) - Mask DesignWare interrupts instead of disabling them to avoid lost interrupts (Marc Zyngier) - Add locking when acking DesignWare interrupts (Marc Zyngier) - Ack DesignWare interrupts in the proper callbacks (Marc Zyngier) - Use devm resource parser in mediatek (Honghui Zhang) - Remove unused mediatek "num-lanes" DT property (Honghui Zhang) - Add UniPhier PCIe controller driver and DT bindings (Kunihiko Hayashi) - Enable MSI for imx6 downstream components (Richard Zhu) * tag 'pci-v4.21-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (40 commits) PCI: imx: Enable MSI from downstream components s390/pci: skip VF scanning PCI/IOV: Add flag so platforms can skip VF scanning PCI/IOV: Factor out sriov_add_vfs() PCI: uniphier: Add UniPhier PCIe host controller support dt-bindings: PCI: Add UniPhier PCIe host controller description PCI: amlogic: Add the Amlogic Meson PCIe controller driver dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller arm64: dts: mt7622: Remove un-used property for PCIe arm: dts: mt7623: Remove un-used property for PCIe dt-bindings: PCI: MediaTek: Remove un-used property PCI: mediatek: Remove un-used variant in struct mtk_pcie_port MAINTAINERS: Remove Jianguo Sun from HiSilicon STB DWC entry PCI: dwc: Don't hard-code DBI/ATU offset PCI: imx: Add imx6sx suspend/resume support PCI: armada8k: Add support for gpio controlled reset signal PCI: dwc: Adjust Kconfig to allow IMX6 PCIe host on IMX7 PCI: dwc: layerscape: Constify driver data PCI: imx: Add multi-pd support PCI: Override Synopsys USB 3.x HAPS device class ...
Diffstat (limited to 'drivers/pci/controller/dwc')
-rw-r--r--drivers/pci/controller/dwc/Kconfig24
-rw-r--r--drivers/pci/controller/dwc/Makefile2
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c102
-rw-r--r--drivers/pci/controller/dwc/pci-layerscape.c10
-rw-r--r--drivers/pci/controller/dwc/pci-meson.c592
-rw-r--r--drivers/pci/controller/dwc/pcie-armada8k.c16
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-ep.c4
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-host.c40
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.c8
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.h28
-rw-r--r--drivers/pci/controller/dwc/pcie-histb.c2
-rw-r--r--drivers/pci/controller/dwc/pcie-uniphier.c471
12 files changed, 1265 insertions, 34 deletions
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 91b0194240a5..548c58223868 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -89,8 +89,8 @@ config PCI_EXYNOS
89 select PCIE_DW_HOST 89 select PCIE_DW_HOST
90 90
91config PCI_IMX6 91config PCI_IMX6
92 bool "Freescale i.MX6 PCIe controller" 92 bool "Freescale i.MX6/7 PCIe controller"
93 depends on SOC_IMX6Q || (ARM && COMPILE_TEST) 93 depends on SOC_IMX6Q || SOC_IMX7D || (ARM && COMPILE_TEST)
94 depends on PCI_MSI_IRQ_DOMAIN 94 depends on PCI_MSI_IRQ_DOMAIN
95 select PCIE_DW_HOST 95 select PCIE_DW_HOST
96 96
@@ -193,4 +193,24 @@ config PCIE_HISI_STB
193 help 193 help
194 Say Y here if you want PCIe controller support on HiSilicon STB SoCs 194 Say Y here if you want PCIe controller support on HiSilicon STB SoCs
195 195
196config PCI_MESON
197 bool "MESON PCIe controller"
198 depends on PCI_MSI_IRQ_DOMAIN
199 select PCIE_DW_HOST
200 help
201 Say Y here if you want to enable PCI controller support on Amlogic
202 SoCs. The PCI controller on Amlogic is based on DesignWare hardware
203 and therefore the driver re-uses the DesignWare core functions to
204 implement the driver.
205
206config PCIE_UNIPHIER
207 bool "Socionext UniPhier PCIe controllers"
208 depends on ARCH_UNIPHIER || COMPILE_TEST
209 depends on OF && HAS_IOMEM
210 depends on PCI_MSI_IRQ_DOMAIN
211 select PCIE_DW_HOST
212 help
213 Say Y here if you want PCIe controller support on UniPhier SoCs.
214 This driver supports LD20 and PXs3 SoCs.
215
196endmenu 216endmenu
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index fcf91eacfc63..7bcdcdf5024e 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
14obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o 14obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
15obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o 15obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o
16obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o 16obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
17obj-$(CONFIG_PCI_MESON) += pci-meson.o
18obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
17 19
18# The following drivers are for devices that use the generic ACPI 20# The following drivers are for devices that use the generic ACPI
19# pci_root.c driver but don't support standard ECAM config access. 21# pci_root.c driver but don't support standard ECAM config access.
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 88af6bff945f..52e47dac028f 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -27,6 +27,8 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/reset.h> 29#include <linux/reset.h>
30#include <linux/pm_domain.h>
31#include <linux/pm_runtime.h>
30 32
31#include "pcie-designware.h" 33#include "pcie-designware.h"
32 34
@@ -59,6 +61,11 @@ struct imx6_pcie {
59 u32 tx_swing_low; 61 u32 tx_swing_low;
60 int link_gen; 62 int link_gen;
61 struct regulator *vpcie; 63 struct regulator *vpcie;
64
65 /* power domain for pcie */
66 struct device *pd_pcie;
67 /* power domain for pcie phy */
68 struct device *pd_pcie_phy;
62}; 69};
63 70
64/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ 71/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -67,6 +74,7 @@ struct imx6_pcie {
67#define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200 74#define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200
68 75
69/* PCIe Root Complex registers (memory-mapped) */ 76/* PCIe Root Complex registers (memory-mapped) */
77#define PCIE_RC_IMX6_MSI_CAP 0x50
70#define PCIE_RC_LCR 0x7c 78#define PCIE_RC_LCR 0x7c
71#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1 79#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1
72#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2 80#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2
@@ -290,6 +298,43 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
290 return 1; 298 return 1;
291} 299}
292 300
301static int imx6_pcie_attach_pd(struct device *dev)
302{
303 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
304 struct device_link *link;
305
306 /* Do nothing when in a single power domain */
307 if (dev->pm_domain)
308 return 0;
309
310 imx6_pcie->pd_pcie = dev_pm_domain_attach_by_name(dev, "pcie");
311 if (IS_ERR(imx6_pcie->pd_pcie))
312 return PTR_ERR(imx6_pcie->pd_pcie);
313 link = device_link_add(dev, imx6_pcie->pd_pcie,
314 DL_FLAG_STATELESS |
315 DL_FLAG_PM_RUNTIME |
316 DL_FLAG_RPM_ACTIVE);
317 if (!link) {
318 dev_err(dev, "Failed to add device_link to pcie pd.\n");
319 return -EINVAL;
320 }
321
322 imx6_pcie->pd_pcie_phy = dev_pm_domain_attach_by_name(dev, "pcie_phy");
323 if (IS_ERR(imx6_pcie->pd_pcie_phy))
324 return PTR_ERR(imx6_pcie->pd_pcie_phy);
325
326 device_link_add(dev, imx6_pcie->pd_pcie_phy,
327 DL_FLAG_STATELESS |
328 DL_FLAG_PM_RUNTIME |
329 DL_FLAG_RPM_ACTIVE);
330 if (IS_ERR(link)) {
331 dev_err(dev, "Failed to add device_link to pcie_phy pd: %ld\n", PTR_ERR(link));
332 return PTR_ERR(link);
333 }
334
335 return 0;
336}
337
293static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) 338static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
294{ 339{
295 struct device *dev = imx6_pcie->pci->dev; 340 struct device *dev = imx6_pcie->pci->dev;
@@ -765,8 +810,28 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
765 810
766static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie) 811static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
767{ 812{
768 reset_control_assert(imx6_pcie->turnoff_reset); 813 struct device *dev = imx6_pcie->pci->dev;
769 reset_control_deassert(imx6_pcie->turnoff_reset); 814
815 /* Some variants have a turnoff reset in DT */
816 if (imx6_pcie->turnoff_reset) {
817 reset_control_assert(imx6_pcie->turnoff_reset);
818 reset_control_deassert(imx6_pcie->turnoff_reset);
819 goto pm_turnoff_sleep;
820 }
821
822 /* Others poke directly at IOMUXC registers */
823 switch (imx6_pcie->variant) {
824 case IMX6SX:
825 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
826 IMX6SX_GPR12_PCIE_PM_TURN_OFF,
827 IMX6SX_GPR12_PCIE_PM_TURN_OFF);
828 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
829 IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0);
830 break;
831 default:
832 dev_err(dev, "PME_Turn_Off not implemented\n");
833 return;
834 }
770 835
771 /* 836 /*
772 * Components with an upstream port must respond to 837 * Components with an upstream port must respond to
@@ -775,6 +840,7 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
775 * The standard recommends a 1-10ms timeout after which to 840 * The standard recommends a 1-10ms timeout after which to
776 * proceed anyway as if acks were received. 841 * proceed anyway as if acks were received.
777 */ 842 */
843pm_turnoff_sleep:
778 usleep_range(1000, 10000); 844 usleep_range(1000, 10000);
779} 845}
780 846
@@ -784,18 +850,31 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
784 clk_disable_unprepare(imx6_pcie->pcie_phy); 850 clk_disable_unprepare(imx6_pcie->pcie_phy);
785 clk_disable_unprepare(imx6_pcie->pcie_bus); 851 clk_disable_unprepare(imx6_pcie->pcie_bus);
786 852
787 if (imx6_pcie->variant == IMX7D) { 853 switch (imx6_pcie->variant) {
854 case IMX6SX:
855 clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
856 break;
857 case IMX7D:
788 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, 858 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
789 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 859 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
790 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); 860 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
861 break;
862 default:
863 break;
791 } 864 }
792} 865}
793 866
867static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie)
868{
869 return (imx6_pcie->variant == IMX7D ||
870 imx6_pcie->variant == IMX6SX);
871}
872
794static int imx6_pcie_suspend_noirq(struct device *dev) 873static int imx6_pcie_suspend_noirq(struct device *dev)
795{ 874{
796 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); 875 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
797 876
798 if (imx6_pcie->variant != IMX7D) 877 if (!imx6_pcie_supports_suspend(imx6_pcie))
799 return 0; 878 return 0;
800 879
801 imx6_pcie_pm_turnoff(imx6_pcie); 880 imx6_pcie_pm_turnoff(imx6_pcie);
@@ -811,7 +890,7 @@ static int imx6_pcie_resume_noirq(struct device *dev)
811 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); 890 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
812 struct pcie_port *pp = &imx6_pcie->pci->pp; 891 struct pcie_port *pp = &imx6_pcie->pci->pp;
813 892
814 if (imx6_pcie->variant != IMX7D) 893 if (!imx6_pcie_supports_suspend(imx6_pcie))
815 return 0; 894 return 0;
816 895
817 imx6_pcie_assert_core_reset(imx6_pcie); 896 imx6_pcie_assert_core_reset(imx6_pcie);
@@ -840,6 +919,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
840 struct resource *dbi_base; 919 struct resource *dbi_base;
841 struct device_node *node = dev->of_node; 920 struct device_node *node = dev->of_node;
842 int ret; 921 int ret;
922 u16 val;
843 923
844 imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL); 924 imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
845 if (!imx6_pcie) 925 if (!imx6_pcie)
@@ -977,10 +1057,22 @@ static int imx6_pcie_probe(struct platform_device *pdev)
977 1057
978 platform_set_drvdata(pdev, imx6_pcie); 1058 platform_set_drvdata(pdev, imx6_pcie);
979 1059
1060 ret = imx6_pcie_attach_pd(dev);
1061 if (ret)
1062 return ret;
1063
980 ret = imx6_add_pcie_port(imx6_pcie, pdev); 1064 ret = imx6_add_pcie_port(imx6_pcie, pdev);
981 if (ret < 0) 1065 if (ret < 0)
982 return ret; 1066 return ret;
983 1067
1068 if (pci_msi_enabled()) {
1069 val = dw_pcie_readw_dbi(pci, PCIE_RC_IMX6_MSI_CAP +
1070 PCI_MSI_FLAGS);
1071 val |= PCI_MSI_FLAGS_ENABLE;
1072 dw_pcie_writew_dbi(pci, PCIE_RC_IMX6_MSI_CAP + PCI_MSI_FLAGS,
1073 val);
1074 }
1075
984 return 0; 1076 return 0;
985} 1077}
986 1078
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index 7aa9a82b7ebd..ce45bde29bf8 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -222,12 +222,12 @@ static const struct dw_pcie_ops dw_ls_pcie_ops = {
222 .link_up = ls_pcie_link_up, 222 .link_up = ls_pcie_link_up,
223}; 223};
224 224
225static struct ls_pcie_drvdata ls1021_drvdata = { 225static const struct ls_pcie_drvdata ls1021_drvdata = {
226 .ops = &ls1021_pcie_host_ops, 226 .ops = &ls1021_pcie_host_ops,
227 .dw_pcie_ops = &dw_ls1021_pcie_ops, 227 .dw_pcie_ops = &dw_ls1021_pcie_ops,
228}; 228};
229 229
230static struct ls_pcie_drvdata ls1043_drvdata = { 230static const struct ls_pcie_drvdata ls1043_drvdata = {
231 .lut_offset = 0x10000, 231 .lut_offset = 0x10000,
232 .ltssm_shift = 24, 232 .ltssm_shift = 24,
233 .lut_dbg = 0x7fc, 233 .lut_dbg = 0x7fc,
@@ -235,7 +235,7 @@ static struct ls_pcie_drvdata ls1043_drvdata = {
235 .dw_pcie_ops = &dw_ls_pcie_ops, 235 .dw_pcie_ops = &dw_ls_pcie_ops,
236}; 236};
237 237
238static struct ls_pcie_drvdata ls1046_drvdata = { 238static const struct ls_pcie_drvdata ls1046_drvdata = {
239 .lut_offset = 0x80000, 239 .lut_offset = 0x80000,
240 .ltssm_shift = 24, 240 .ltssm_shift = 24,
241 .lut_dbg = 0x407fc, 241 .lut_dbg = 0x407fc,
@@ -243,7 +243,7 @@ static struct ls_pcie_drvdata ls1046_drvdata = {
243 .dw_pcie_ops = &dw_ls_pcie_ops, 243 .dw_pcie_ops = &dw_ls_pcie_ops,
244}; 244};
245 245
246static struct ls_pcie_drvdata ls2080_drvdata = { 246static const struct ls_pcie_drvdata ls2080_drvdata = {
247 .lut_offset = 0x80000, 247 .lut_offset = 0x80000,
248 .ltssm_shift = 0, 248 .ltssm_shift = 0,
249 .lut_dbg = 0x7fc, 249 .lut_dbg = 0x7fc,
@@ -251,7 +251,7 @@ static struct ls_pcie_drvdata ls2080_drvdata = {
251 .dw_pcie_ops = &dw_ls_pcie_ops, 251 .dw_pcie_ops = &dw_ls_pcie_ops,
252}; 252};
253 253
254static struct ls_pcie_drvdata ls2088_drvdata = { 254static const struct ls_pcie_drvdata ls2088_drvdata = {
255 .lut_offset = 0x80000, 255 .lut_offset = 0x80000,
256 .ltssm_shift = 0, 256 .ltssm_shift = 0,
257 .lut_dbg = 0x407fc, 257 .lut_dbg = 0x407fc,
diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
new file mode 100644
index 000000000000..241ebe0c4505
--- /dev/null
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -0,0 +1,592 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * PCIe host controller driver for Amlogic MESON SoCs
4 *
5 * Copyright (c) 2018 Amlogic, inc.
6 * Author: Yue Wang <yue.wang@amlogic.com>
7 */
8
9#include <linux/clk.h>
10#include <linux/delay.h>
11#include <linux/of_device.h>
12#include <linux/of_gpio.h>
13#include <linux/pci.h>
14#include <linux/platform_device.h>
15#include <linux/reset.h>
16#include <linux/resource.h>
17#include <linux/types.h>
18
19#include "pcie-designware.h"
20
21#define to_meson_pcie(x) dev_get_drvdata((x)->dev)
22
23/* External local bus interface registers */
24#define PLR_OFFSET 0x700
25#define PCIE_PORT_LINK_CTRL_OFF (PLR_OFFSET + 0x10)
26#define FAST_LINK_MODE BIT(7)
27#define LINK_CAPABLE_MASK GENMASK(21, 16)
28#define LINK_CAPABLE_X1 BIT(16)
29
30#define PCIE_GEN2_CTRL_OFF (PLR_OFFSET + 0x10c)
31#define NUM_OF_LANES_MASK GENMASK(12, 8)
32#define NUM_OF_LANES_X1 BIT(8)
33#define DIRECT_SPEED_CHANGE BIT(17)
34
35#define TYPE1_HDR_OFFSET 0x0
36#define PCIE_STATUS_COMMAND (TYPE1_HDR_OFFSET + 0x04)
37#define PCI_IO_EN BIT(0)
38#define PCI_MEM_SPACE_EN BIT(1)
39#define PCI_BUS_MASTER_EN BIT(2)
40
41#define PCIE_BASE_ADDR0 (TYPE1_HDR_OFFSET + 0x10)
42#define PCIE_BASE_ADDR1 (TYPE1_HDR_OFFSET + 0x14)
43
44#define PCIE_CAP_OFFSET 0x70
45#define PCIE_DEV_CTRL_DEV_STUS (PCIE_CAP_OFFSET + 0x08)
46#define PCIE_CAP_MAX_PAYLOAD_MASK GENMASK(7, 5)
47#define PCIE_CAP_MAX_PAYLOAD_SIZE(x) ((x) << 5)
48#define PCIE_CAP_MAX_READ_REQ_MASK GENMASK(14, 12)
49#define PCIE_CAP_MAX_READ_REQ_SIZE(x) ((x) << 12)
50
51/* PCIe specific config registers */
52#define PCIE_CFG0 0x0
53#define APP_LTSSM_ENABLE BIT(7)
54
55#define PCIE_CFG_STATUS12 0x30
56#define IS_SMLH_LINK_UP(x) ((x) & (1 << 6))
57#define IS_RDLH_LINK_UP(x) ((x) & (1 << 16))
58#define IS_LTSSM_UP(x) ((((x) >> 10) & 0x1f) == 0x11)
59
60#define PCIE_CFG_STATUS17 0x44
61#define PM_CURRENT_STATE(x) (((x) >> 7) & 0x1)
62
63#define WAIT_LINKUP_TIMEOUT 4000
64#define PORT_CLK_RATE 100000000UL
65#define MAX_PAYLOAD_SIZE 256
66#define MAX_READ_REQ_SIZE 256
67#define MESON_PCIE_PHY_POWERUP 0x1c
68#define PCIE_RESET_DELAY 500
69#define PCIE_SHARED_RESET 1
70#define PCIE_NORMAL_RESET 0
71
72enum pcie_data_rate {
73 PCIE_GEN1,
74 PCIE_GEN2,
75 PCIE_GEN3,
76 PCIE_GEN4
77};
78
79struct meson_pcie_mem_res {
80 void __iomem *elbi_base;
81 void __iomem *cfg_base;
82 void __iomem *phy_base;
83};
84
85struct meson_pcie_clk_res {
86 struct clk *clk;
87 struct clk *mipi_gate;
88 struct clk *port_clk;
89 struct clk *general_clk;
90};
91
92struct meson_pcie_rc_reset {
93 struct reset_control *phy;
94 struct reset_control *port;
95 struct reset_control *apb;
96};
97
98struct meson_pcie {
99 struct dw_pcie pci;
100 struct meson_pcie_mem_res mem_res;
101 struct meson_pcie_clk_res clk_res;
102 struct meson_pcie_rc_reset mrst;
103 struct gpio_desc *reset_gpio;
104};
105
106static struct reset_control *meson_pcie_get_reset(struct meson_pcie *mp,
107 const char *id,
108 u32 reset_type)
109{
110 struct device *dev = mp->pci.dev;
111 struct reset_control *reset;
112
113 if (reset_type == PCIE_SHARED_RESET)
114 reset = devm_reset_control_get_shared(dev, id);
115 else
116 reset = devm_reset_control_get(dev, id);
117
118 return reset;
119}
120
121static int meson_pcie_get_resets(struct meson_pcie *mp)
122{
123 struct meson_pcie_rc_reset *mrst = &mp->mrst;
124
125 mrst->phy = meson_pcie_get_reset(mp, "phy", PCIE_SHARED_RESET);
126 if (IS_ERR(mrst->phy))
127 return PTR_ERR(mrst->phy);
128 reset_control_deassert(mrst->phy);
129
130 mrst->port = meson_pcie_get_reset(mp, "port", PCIE_NORMAL_RESET);
131 if (IS_ERR(mrst->port))
132 return PTR_ERR(mrst->port);
133 reset_control_deassert(mrst->port);
134
135 mrst->apb = meson_pcie_get_reset(mp, "apb", PCIE_SHARED_RESET);
136 if (IS_ERR(mrst->apb))
137 return PTR_ERR(mrst->apb);
138 reset_control_deassert(mrst->apb);
139
140 return 0;
141}
142
143static void __iomem *meson_pcie_get_mem(struct platform_device *pdev,
144 struct meson_pcie *mp,
145 const char *id)
146{
147 struct device *dev = mp->pci.dev;
148 struct resource *res;
149
150 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, id);
151
152 return devm_ioremap_resource(dev, res);
153}
154
155static void __iomem *meson_pcie_get_mem_shared(struct platform_device *pdev,
156 struct meson_pcie *mp,
157 const char *id)
158{
159 struct device *dev = mp->pci.dev;
160 struct resource *res;
161
162 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, id);
163 if (!res) {
164 dev_err(dev, "No REG resource %s\n", id);
165 return ERR_PTR(-ENXIO);
166 }
167
168 return devm_ioremap(dev, res->start, resource_size(res));
169}
170
171static int meson_pcie_get_mems(struct platform_device *pdev,
172 struct meson_pcie *mp)
173{
174 mp->mem_res.elbi_base = meson_pcie_get_mem(pdev, mp, "elbi");
175 if (IS_ERR(mp->mem_res.elbi_base))
176 return PTR_ERR(mp->mem_res.elbi_base);
177
178 mp->mem_res.cfg_base = meson_pcie_get_mem(pdev, mp, "cfg");
179 if (IS_ERR(mp->mem_res.cfg_base))
180 return PTR_ERR(mp->mem_res.cfg_base);
181
182 /* Meson SoC has two PCI controllers use same phy register*/
183 mp->mem_res.phy_base = meson_pcie_get_mem_shared(pdev, mp, "phy");
184 if (IS_ERR(mp->mem_res.phy_base))
185 return PTR_ERR(mp->mem_res.phy_base);
186
187 return 0;
188}
189
190static void meson_pcie_power_on(struct meson_pcie *mp)
191{
192 writel(MESON_PCIE_PHY_POWERUP, mp->mem_res.phy_base);
193}
194
195static void meson_pcie_reset(struct meson_pcie *mp)
196{
197 struct meson_pcie_rc_reset *mrst = &mp->mrst;
198
199 reset_control_assert(mrst->phy);
200 udelay(PCIE_RESET_DELAY);
201 reset_control_deassert(mrst->phy);
202 udelay(PCIE_RESET_DELAY);
203
204 reset_control_assert(mrst->port);
205 reset_control_assert(mrst->apb);
206 udelay(PCIE_RESET_DELAY);
207 reset_control_deassert(mrst->port);
208 reset_control_deassert(mrst->apb);
209 udelay(PCIE_RESET_DELAY);
210}
211
212static inline struct clk *meson_pcie_probe_clock(struct device *dev,
213 const char *id, u64 rate)
214{
215 struct clk *clk;
216 int ret;
217
218 clk = devm_clk_get(dev, id);
219 if (IS_ERR(clk))
220 return clk;
221
222 if (rate) {
223 ret = clk_set_rate(clk, rate);
224 if (ret) {
225 dev_err(dev, "set clk rate failed, ret = %d\n", ret);
226 return ERR_PTR(ret);
227 }
228 }
229
230 ret = clk_prepare_enable(clk);
231 if (ret) {
232 dev_err(dev, "couldn't enable clk\n");
233 return ERR_PTR(ret);
234 }
235
236 devm_add_action_or_reset(dev,
237 (void (*) (void *))clk_disable_unprepare,
238 clk);
239
240 return clk;
241}
242
243static int meson_pcie_probe_clocks(struct meson_pcie *mp)
244{
245 struct device *dev = mp->pci.dev;
246 struct meson_pcie_clk_res *res = &mp->clk_res;
247
248 res->port_clk = meson_pcie_probe_clock(dev, "port", PORT_CLK_RATE);
249 if (IS_ERR(res->port_clk))
250 return PTR_ERR(res->port_clk);
251
252 res->mipi_gate = meson_pcie_probe_clock(dev, "pcie_mipi_en", 0);
253 if (IS_ERR(res->mipi_gate))
254 return PTR_ERR(res->mipi_gate);
255
256 res->general_clk = meson_pcie_probe_clock(dev, "pcie_general", 0);
257 if (IS_ERR(res->general_clk))
258 return PTR_ERR(res->general_clk);
259
260 res->clk = meson_pcie_probe_clock(dev, "pcie", 0);
261 if (IS_ERR(res->clk))
262 return PTR_ERR(res->clk);
263
264 return 0;
265}
266
267static inline void meson_elb_writel(struct meson_pcie *mp, u32 val, u32 reg)
268{
269 writel(val, mp->mem_res.elbi_base + reg);
270}
271
272static inline u32 meson_elb_readl(struct meson_pcie *mp, u32 reg)
273{
274 return readl(mp->mem_res.elbi_base + reg);
275}
276
277static inline u32 meson_cfg_readl(struct meson_pcie *mp, u32 reg)
278{
279 return readl(mp->mem_res.cfg_base + reg);
280}
281
282static inline void meson_cfg_writel(struct meson_pcie *mp, u32 val, u32 reg)
283{
284 writel(val, mp->mem_res.cfg_base + reg);
285}
286
287static void meson_pcie_assert_reset(struct meson_pcie *mp)
288{
289 gpiod_set_value_cansleep(mp->reset_gpio, 0);
290 udelay(500);
291 gpiod_set_value_cansleep(mp->reset_gpio, 1);
292}
293
294static void meson_pcie_init_dw(struct meson_pcie *mp)
295{
296 u32 val;
297
298 val = meson_cfg_readl(mp, PCIE_CFG0);
299 val |= APP_LTSSM_ENABLE;
300 meson_cfg_writel(mp, val, PCIE_CFG0);
301
302 val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF);
303 val &= ~LINK_CAPABLE_MASK;
304 meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF);
305
306 val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF);
307 val |= LINK_CAPABLE_X1 | FAST_LINK_MODE;
308 meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF);
309
310 val = meson_elb_readl(mp, PCIE_GEN2_CTRL_OFF);
311 val &= ~NUM_OF_LANES_MASK;
312 meson_elb_writel(mp, val, PCIE_GEN2_CTRL_OFF);
313
314 val = meson_elb_readl(mp, PCIE_GEN2_CTRL_OFF);
315 val |= NUM_OF_LANES_X1 | DIRECT_SPEED_CHANGE;
316 meson_elb_writel(mp, val, PCIE_GEN2_CTRL_OFF);
317
318 meson_elb_writel(mp, 0x0, PCIE_BASE_ADDR0);
319 meson_elb_writel(mp, 0x0, PCIE_BASE_ADDR1);
320}
321
322static int meson_size_to_payload(struct meson_pcie *mp, int size)
323{
324 struct device *dev = mp->pci.dev;
325
326 /*
327 * dwc supports 2^(val+7) payload size, which val is 0~5 default to 1.
328 * So if input size is not 2^order alignment or less than 2^7 or bigger
329 * than 2^12, just set to default size 2^(1+7).
330 */
331 if (!is_power_of_2(size) || size < 128 || size > 4096) {
332 dev_warn(dev, "payload size %d, set to default 256\n", size);
333 return 1;
334 }
335
336 return fls(size) - 8;
337}
338
339static void meson_set_max_payload(struct meson_pcie *mp, int size)
340{
341 u32 val;
342 int max_payload_size = meson_size_to_payload(mp, size);
343
344 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
345 val &= ~PCIE_CAP_MAX_PAYLOAD_MASK;
346 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
347
348 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
349 val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size);
350 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
351}
352
353static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size)
354{
355 u32 val;
356 int max_rd_req_size = meson_size_to_payload(mp, size);
357
358 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
359 val &= ~PCIE_CAP_MAX_READ_REQ_MASK;
360 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
361
362 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
363 val |= PCIE_CAP_MAX_READ_REQ_SIZE(max_rd_req_size);
364 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
365}
366
367static inline void meson_enable_memory_space(struct meson_pcie *mp)
368{
369 /* Set the RC Bus Master, Memory Space and I/O Space enables */
370 meson_elb_writel(mp, PCI_IO_EN | PCI_MEM_SPACE_EN | PCI_BUS_MASTER_EN,
371 PCIE_STATUS_COMMAND);
372}
373
374static int meson_pcie_establish_link(struct meson_pcie *mp)
375{
376 struct dw_pcie *pci = &mp->pci;
377 struct pcie_port *pp = &pci->pp;
378
379 meson_pcie_init_dw(mp);
380 meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
381 meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
382
383 dw_pcie_setup_rc(pp);
384 meson_enable_memory_space(mp);
385
386 meson_pcie_assert_reset(mp);
387
388 return dw_pcie_wait_for_link(pci);
389}
390
391static void meson_pcie_enable_interrupts(struct meson_pcie *mp)
392{
393 if (IS_ENABLED(CONFIG_PCI_MSI))
394 dw_pcie_msi_init(&mp->pci.pp);
395}
396
397static int meson_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
398 u32 *val)
399{
400 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
401 int ret;
402
403 ret = dw_pcie_read(pci->dbi_base + where, size, val);
404 if (ret != PCIBIOS_SUCCESSFUL)
405 return ret;
406
407 /*
408 * There is a bug in the MESON AXG PCIe controller whereby software
409 * cannot program the PCI_CLASS_DEVICE register, so we must fabricate
410 * the return value in the config accessors.
411 */
412 if (where == PCI_CLASS_REVISION && size == 4)
413 *val = (PCI_CLASS_BRIDGE_PCI << 16) | (*val & 0xffff);
414 else if (where == PCI_CLASS_DEVICE && size == 2)
415 *val = PCI_CLASS_BRIDGE_PCI;
416 else if (where == PCI_CLASS_DEVICE && size == 1)
417 *val = PCI_CLASS_BRIDGE_PCI & 0xff;
418 else if (where == PCI_CLASS_DEVICE + 1 && size == 1)
419 *val = (PCI_CLASS_BRIDGE_PCI >> 8) & 0xff;
420
421 return PCIBIOS_SUCCESSFUL;
422}
423
424static int meson_pcie_wr_own_conf(struct pcie_port *pp, int where,
425 int size, u32 val)
426{
427 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
428
429 return dw_pcie_write(pci->dbi_base + where, size, val);
430}
431
432static int meson_pcie_link_up(struct dw_pcie *pci)
433{
434 struct meson_pcie *mp = to_meson_pcie(pci);
435 struct device *dev = pci->dev;
436 u32 speed_okay = 0;
437 u32 cnt = 0;
438 u32 state12, state17, smlh_up, ltssm_up, rdlh_up;
439
440 do {
441 state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12);
442 state17 = meson_cfg_readl(mp, PCIE_CFG_STATUS17);
443 smlh_up = IS_SMLH_LINK_UP(state12);
444 rdlh_up = IS_RDLH_LINK_UP(state12);
445 ltssm_up = IS_LTSSM_UP(state12);
446
447 if (PM_CURRENT_STATE(state17) < PCIE_GEN3)
448 speed_okay = 1;
449
450 if (smlh_up)
451 dev_dbg(dev, "smlh_link_up is on\n");
452 if (rdlh_up)
453 dev_dbg(dev, "rdlh_link_up is on\n");
454 if (ltssm_up)
455 dev_dbg(dev, "ltssm_up is on\n");
456 if (speed_okay)
457 dev_dbg(dev, "speed_okay\n");
458
459 if (smlh_up && rdlh_up && ltssm_up && speed_okay)
460 return 1;
461
462 cnt++;
463
464 udelay(10);
465 } while (cnt < WAIT_LINKUP_TIMEOUT);
466
467 dev_err(dev, "error: wait linkup timeout\n");
468 return 0;
469}
470
471static int meson_pcie_host_init(struct pcie_port *pp)
472{
473 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
474 struct meson_pcie *mp = to_meson_pcie(pci);
475 int ret;
476
477 ret = meson_pcie_establish_link(mp);
478 if (ret)
479 return ret;
480
481 meson_pcie_enable_interrupts(mp);
482
483 return 0;
484}
485
486static const struct dw_pcie_host_ops meson_pcie_host_ops = {
487 .rd_own_conf = meson_pcie_rd_own_conf,
488 .wr_own_conf = meson_pcie_wr_own_conf,
489 .host_init = meson_pcie_host_init,
490};
491
492static int meson_add_pcie_port(struct meson_pcie *mp,
493 struct platform_device *pdev)
494{
495 struct dw_pcie *pci = &mp->pci;
496 struct pcie_port *pp = &pci->pp;
497 struct device *dev = &pdev->dev;
498 int ret;
499
500 if (IS_ENABLED(CONFIG_PCI_MSI)) {
501 pp->msi_irq = platform_get_irq(pdev, 0);
502 if (pp->msi_irq < 0) {
503 dev_err(dev, "failed to get MSI IRQ\n");
504 return pp->msi_irq;
505 }
506 }
507
508 pp->ops = &meson_pcie_host_ops;
509 pci->dbi_base = mp->mem_res.elbi_base;
510
511 ret = dw_pcie_host_init(pp);
512 if (ret) {
513 dev_err(dev, "failed to initialize host\n");
514 return ret;
515 }
516
517 return 0;
518}
519
520static const struct dw_pcie_ops dw_pcie_ops = {
521 .link_up = meson_pcie_link_up,
522};
523
524static int meson_pcie_probe(struct platform_device *pdev)
525{
526 struct device *dev = &pdev->dev;
527 struct dw_pcie *pci;
528 struct meson_pcie *mp;
529 int ret;
530
531 mp = devm_kzalloc(dev, sizeof(*mp), GFP_KERNEL);
532 if (!mp)
533 return -ENOMEM;
534
535 pci = &mp->pci;
536 pci->dev = dev;
537 pci->ops = &dw_pcie_ops;
538
539 mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
540 if (IS_ERR(mp->reset_gpio)) {
541 dev_err(dev, "get reset gpio failed\n");
542 return PTR_ERR(mp->reset_gpio);
543 }
544
545 ret = meson_pcie_get_resets(mp);
546 if (ret) {
547 dev_err(dev, "get reset resource failed, %d\n", ret);
548 return ret;
549 }
550
551 ret = meson_pcie_get_mems(pdev, mp);
552 if (ret) {
553 dev_err(dev, "get memory resource failed, %d\n", ret);
554 return ret;
555 }
556
557 meson_pcie_power_on(mp);
558 meson_pcie_reset(mp);
559
560 ret = meson_pcie_probe_clocks(mp);
561 if (ret) {
562 dev_err(dev, "init clock resources failed, %d\n", ret);
563 return ret;
564 }
565
566 platform_set_drvdata(pdev, mp);
567
568 ret = meson_add_pcie_port(mp, pdev);
569 if (ret < 0) {
570 dev_err(dev, "Add PCIe port failed, %d\n", ret);
571 return ret;
572 }
573
574 return 0;
575}
576
577static const struct of_device_id meson_pcie_of_match[] = {
578 {
579 .compatible = "amlogic,axg-pcie",
580 },
581 {},
582};
583
584static struct platform_driver meson_pcie_driver = {
585 .probe = meson_pcie_probe,
586 .driver = {
587 .name = "meson-pcie",
588 .of_match_table = meson_pcie_of_match,
589 },
590};
591
592builtin_platform_driver(meson_pcie_driver);
diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
index 0c389a30ef5d..b171b6bc15c8 100644
--- a/drivers/pci/controller/dwc/pcie-armada8k.c
+++ b/drivers/pci/controller/dwc/pcie-armada8k.c
@@ -22,6 +22,7 @@
22#include <linux/resource.h> 22#include <linux/resource.h>
23#include <linux/of_pci.h> 23#include <linux/of_pci.h>
24#include <linux/of_irq.h> 24#include <linux/of_irq.h>
25#include <linux/gpio/consumer.h>
25 26
26#include "pcie-designware.h" 27#include "pcie-designware.h"
27 28
@@ -29,6 +30,7 @@ struct armada8k_pcie {
29 struct dw_pcie *pci; 30 struct dw_pcie *pci;
30 struct clk *clk; 31 struct clk *clk;
31 struct clk *clk_reg; 32 struct clk *clk_reg;
33 struct gpio_desc *reset_gpio;
32}; 34};
33 35
34#define PCIE_VENDOR_REGS_OFFSET 0x8000 36#define PCIE_VENDOR_REGS_OFFSET 0x8000
@@ -137,6 +139,12 @@ static int armada8k_pcie_host_init(struct pcie_port *pp)
137 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 139 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
138 struct armada8k_pcie *pcie = to_armada8k_pcie(pci); 140 struct armada8k_pcie *pcie = to_armada8k_pcie(pci);
139 141
142 if (pcie->reset_gpio) {
143 /* assert and then deassert the reset signal */
144 gpiod_set_value_cansleep(pcie->reset_gpio, 1);
145 msleep(100);
146 gpiod_set_value_cansleep(pcie->reset_gpio, 0);
147 }
140 dw_pcie_setup_rc(pp); 148 dw_pcie_setup_rc(pp);
141 armada8k_pcie_establish_link(pcie); 149 armada8k_pcie_establish_link(pcie);
142 150
@@ -249,6 +257,14 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
249 goto fail_clkreg; 257 goto fail_clkreg;
250 } 258 }
251 259
260 /* Get reset gpio signal and hold asserted (logically high) */
261 pcie->reset_gpio = devm_gpiod_get_optional(dev, "reset",
262 GPIOD_OUT_HIGH);
263 if (IS_ERR(pcie->reset_gpio)) {
264 ret = PTR_ERR(pcie->reset_gpio);
265 goto fail_clkreg;
266 }
267
252 platform_set_drvdata(pdev, pcie); 268 platform_set_drvdata(pdev, pcie);
253 269
254 ret = armada8k_add_pcie_port(pcie, pdev); 270 ret = armada8k_add_pcie_port(pcie, pdev);
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index de8635af4cde..a543c45c7224 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -503,6 +503,10 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
503 dev_err(dev, "dbi_base/dbi_base2 is not populated\n"); 503 dev_err(dev, "dbi_base/dbi_base2 is not populated\n");
504 return -EINVAL; 504 return -EINVAL;
505 } 505 }
506 if (pci->iatu_unroll_enabled && !pci->atu_base) {
507 dev_err(dev, "atu_base is not populated\n");
508 return -EINVAL;
509 }
506 510
507 ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows); 511 ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows);
508 if (ret < 0) { 512 if (ret < 0) {
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 29a05759a294..721d60a5d9e4 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -99,9 +99,6 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
99 (i * MAX_MSI_IRQS_PER_CTRL) + 99 (i * MAX_MSI_IRQS_PER_CTRL) +
100 pos); 100 pos);
101 generic_handle_irq(irq); 101 generic_handle_irq(irq);
102 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS +
103 (i * MSI_REG_CTRL_BLOCK_SIZE),
104 4, 1 << pos);
105 pos++; 102 pos++;
106 } 103 }
107 } 104 }
@@ -168,8 +165,8 @@ static void dw_pci_bottom_mask(struct irq_data *data)
168 bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; 165 bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;
169 166
170 pp->irq_status[ctrl] &= ~(1 << bit); 167 pp->irq_status[ctrl] &= ~(1 << bit);
171 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, 168 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
172 pp->irq_status[ctrl]); 169 ~pp->irq_status[ctrl]);
173 } 170 }
174 171
175 raw_spin_unlock_irqrestore(&pp->lock, flags); 172 raw_spin_unlock_irqrestore(&pp->lock, flags);
@@ -191,8 +188,8 @@ static void dw_pci_bottom_unmask(struct irq_data *data)
191 bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; 188 bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;
192 189
193 pp->irq_status[ctrl] |= 1 << bit; 190 pp->irq_status[ctrl] |= 1 << bit;
194 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, 191 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
195 pp->irq_status[ctrl]); 192 ~pp->irq_status[ctrl]);
196 } 193 }
197 194
198 raw_spin_unlock_irqrestore(&pp->lock, flags); 195 raw_spin_unlock_irqrestore(&pp->lock, flags);
@@ -200,13 +197,22 @@ static void dw_pci_bottom_unmask(struct irq_data *data)
200 197
201static void dw_pci_bottom_ack(struct irq_data *d) 198static void dw_pci_bottom_ack(struct irq_data *d)
202{ 199{
203 struct msi_desc *msi = irq_data_get_msi_desc(d); 200 struct pcie_port *pp = irq_data_get_irq_chip_data(d);
204 struct pcie_port *pp; 201 unsigned int res, bit, ctrl;
202 unsigned long flags;
203
204 ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL;
205 res = ctrl * MSI_REG_CTRL_BLOCK_SIZE;
206 bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL;
207
208 raw_spin_lock_irqsave(&pp->lock, flags);
205 209
206 pp = msi_desc_to_pci_sysdata(msi); 210 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, 1 << bit);
207 211
208 if (pp->ops->msi_irq_ack) 212 if (pp->ops->msi_irq_ack)
209 pp->ops->msi_irq_ack(d->hwirq, pp); 213 pp->ops->msi_irq_ack(d->hwirq, pp);
214
215 raw_spin_unlock_irqrestore(&pp->lock, flags);
210} 216}
211 217
212static struct irq_chip dw_pci_msi_bottom_irq_chip = { 218static struct irq_chip dw_pci_msi_bottom_irq_chip = {
@@ -658,10 +664,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
658 num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; 664 num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
659 665
660 /* Initialize IRQ Status array */ 666 /* Initialize IRQ Status array */
661 for (ctrl = 0; ctrl < num_ctrls; ctrl++) 667 for (ctrl = 0; ctrl < num_ctrls; ctrl++) {
662 dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + 668 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK +
669 (ctrl * MSI_REG_CTRL_BLOCK_SIZE),
670 4, ~0);
671 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE +
663 (ctrl * MSI_REG_CTRL_BLOCK_SIZE), 672 (ctrl * MSI_REG_CTRL_BLOCK_SIZE),
664 4, &pp->irq_status[ctrl]); 673 4, ~0);
674 pp->irq_status[ctrl] = 0;
675 }
665 676
666 /* Setup RC BARs */ 677 /* Setup RC BARs */
667 dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004); 678 dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
@@ -699,6 +710,9 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
699 dev_dbg(pci->dev, "iATU unroll: %s\n", 710 dev_dbg(pci->dev, "iATU unroll: %s\n",
700 pci->iatu_unroll_enabled ? "enabled" : "disabled"); 711 pci->iatu_unroll_enabled ? "enabled" : "disabled");
701 712
713 if (pci->iatu_unroll_enabled && !pci->atu_base)
714 pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
715
702 dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0, 716 dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
703 PCIE_ATU_TYPE_MEM, pp->mem_base, 717 PCIE_ATU_TYPE_MEM, pp->mem_base,
704 pp->mem_bus_addr, pp->mem_size); 718 pp->mem_bus_addr, pp->mem_size);
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 2153956a0b20..93ef8c31fb39 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -93,7 +93,7 @@ static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg)
93{ 93{
94 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); 94 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
95 95
96 return dw_pcie_readl_dbi(pci, offset + reg); 96 return dw_pcie_readl_atu(pci, offset + reg);
97} 97}
98 98
99static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg, 99static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg,
@@ -101,7 +101,7 @@ static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg,
101{ 101{
102 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); 102 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
103 103
104 dw_pcie_writel_dbi(pci, offset + reg, val); 104 dw_pcie_writel_atu(pci, offset + reg, val);
105} 105}
106 106
107static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, 107static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
@@ -187,7 +187,7 @@ static u32 dw_pcie_readl_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg)
187{ 187{
188 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index); 188 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index);
189 189
190 return dw_pcie_readl_dbi(pci, offset + reg); 190 return dw_pcie_readl_atu(pci, offset + reg);
191} 191}
192 192
193static void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg, 193static void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg,
@@ -195,7 +195,7 @@ static void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg,
195{ 195{
196 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index); 196 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index);
197 197
198 dw_pcie_writel_dbi(pci, offset + reg, val); 198 dw_pcie_writel_atu(pci, offset + reg, val);
199} 199}
200 200
201static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index, 201static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 0989d880ac46..9943d8c68335 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -92,12 +92,20 @@
92#define PCIE_ATU_UNR_LOWER_TARGET 0x14 92#define PCIE_ATU_UNR_LOWER_TARGET 0x14
93#define PCIE_ATU_UNR_UPPER_TARGET 0x18 93#define PCIE_ATU_UNR_UPPER_TARGET 0x18
94 94
95/*
96 * The default address offset between dbi_base and atu_base. Root controller
97 * drivers are not required to initialize atu_base if the offset matches this
98 * default; the driver core automatically derives atu_base from dbi_base using
99 * this offset, if atu_base not set.
100 */
101#define DEFAULT_DBI_ATU_OFFSET (0x3 << 20)
102
95/* Register address builder */ 103/* Register address builder */
96#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \ 104#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \
97 ((0x3 << 20) | ((region) << 9)) 105 ((region) << 9)
98 106
99#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ 107#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \
100 ((0x3 << 20) | ((region) << 9) | (0x1 << 8)) 108 (((region) << 9) | (0x1 << 8))
101 109
102#define MAX_MSI_IRQS 256 110#define MAX_MSI_IRQS 256
103#define MAX_MSI_IRQS_PER_CTRL 32 111#define MAX_MSI_IRQS_PER_CTRL 32
@@ -219,6 +227,8 @@ struct dw_pcie {
219 struct device *dev; 227 struct device *dev;
220 void __iomem *dbi_base; 228 void __iomem *dbi_base;
221 void __iomem *dbi_base2; 229 void __iomem *dbi_base2;
230 /* Used when iatu_unroll_enabled is true */
231 void __iomem *atu_base;
222 u32 num_viewport; 232 u32 num_viewport;
223 u8 iatu_unroll_enabled; 233 u8 iatu_unroll_enabled;
224 struct pcie_port pp; 234 struct pcie_port pp;
@@ -289,6 +299,16 @@ static inline u32 dw_pcie_readl_dbi2(struct dw_pcie *pci, u32 reg)
289 return __dw_pcie_read_dbi(pci, pci->dbi_base2, reg, 0x4); 299 return __dw_pcie_read_dbi(pci, pci->dbi_base2, reg, 0x4);
290} 300}
291 301
302static inline void dw_pcie_writel_atu(struct dw_pcie *pci, u32 reg, u32 val)
303{
304 __dw_pcie_write_dbi(pci, pci->atu_base, reg, 0x4, val);
305}
306
307static inline u32 dw_pcie_readl_atu(struct dw_pcie *pci, u32 reg)
308{
309 return __dw_pcie_read_dbi(pci, pci->atu_base, reg, 0x4);
310}
311
292static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci) 312static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci)
293{ 313{
294 u32 reg; 314 u32 reg;
diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
index 7b32e619b959..954bc2b74bbc 100644
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -202,7 +202,7 @@ static int histb_pcie_host_init(struct pcie_port *pp)
202 return 0; 202 return 0;
203} 203}
204 204
205static struct dw_pcie_host_ops histb_pcie_host_ops = { 205static const struct dw_pcie_host_ops histb_pcie_host_ops = {
206 .rd_own_conf = histb_pcie_rd_own_conf, 206 .rd_own_conf = histb_pcie_rd_own_conf,
207 .wr_own_conf = histb_pcie_wr_own_conf, 207 .wr_own_conf = histb_pcie_wr_own_conf,
208 .host_init = histb_pcie_host_init, 208 .host_init = histb_pcie_host_init,
diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
new file mode 100644
index 000000000000..d5dc40289cce
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -0,0 +1,471 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * PCIe host controller driver for UniPhier SoCs
4 * Copyright 2018 Socionext Inc.
5 * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
6 */
7
8#include <linux/bitops.h>
9#include <linux/bitfield.h>
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/interrupt.h>
13#include <linux/iopoll.h>
14#include <linux/irqchip/chained_irq.h>
15#include <linux/irqdomain.h>
16#include <linux/module.h>
17#include <linux/of_irq.h>
18#include <linux/pci.h>
19#include <linux/phy/phy.h>
20#include <linux/platform_device.h>
21#include <linux/reset.h>
22
23#include "pcie-designware.h"
24
25#define PCL_PINCTRL0 0x002c
26#define PCL_PERST_PLDN_REGEN BIT(12)
27#define PCL_PERST_NOE_REGEN BIT(11)
28#define PCL_PERST_OUT_REGEN BIT(8)
29#define PCL_PERST_PLDN_REGVAL BIT(4)
30#define PCL_PERST_NOE_REGVAL BIT(3)
31#define PCL_PERST_OUT_REGVAL BIT(0)
32
33#define PCL_PIPEMON 0x0044
34#define PCL_PCLK_ALIVE BIT(15)
35
36#define PCL_APP_READY_CTRL 0x8008
37#define PCL_APP_LTSSM_ENABLE BIT(0)
38
39#define PCL_APP_PM0 0x8078
40#define PCL_SYS_AUX_PWR_DET BIT(8)
41
42#define PCL_RCV_INT 0x8108
43#define PCL_RCV_INT_ALL_ENABLE GENMASK(20, 17)
44#define PCL_CFG_BW_MGT_STATUS BIT(4)
45#define PCL_CFG_LINK_AUTO_BW_STATUS BIT(3)
46#define PCL_CFG_AER_RC_ERR_MSI_STATUS BIT(2)
47#define PCL_CFG_PME_MSI_STATUS BIT(1)
48
49#define PCL_RCV_INTX 0x810c
50#define PCL_RCV_INTX_ALL_ENABLE GENMASK(19, 16)
51#define PCL_RCV_INTX_ALL_MASK GENMASK(11, 8)
52#define PCL_RCV_INTX_MASK_SHIFT 8
53#define PCL_RCV_INTX_ALL_STATUS GENMASK(3, 0)
54#define PCL_RCV_INTX_STATUS_SHIFT 0
55
56#define PCL_STATUS_LINK 0x8140
57#define PCL_RDLH_LINK_UP BIT(1)
58#define PCL_XMLH_LINK_UP BIT(0)
59
60struct uniphier_pcie_priv {
61 void __iomem *base;
62 struct dw_pcie pci;
63 struct clk *clk;
64 struct reset_control *rst;
65 struct phy *phy;
66 struct irq_domain *legacy_irq_domain;
67};
68
69#define to_uniphier_pcie(x) dev_get_drvdata((x)->dev)
70
71static void uniphier_pcie_ltssm_enable(struct uniphier_pcie_priv *priv,
72 bool enable)
73{
74 u32 val;
75
76 val = readl(priv->base + PCL_APP_READY_CTRL);
77 if (enable)
78 val |= PCL_APP_LTSSM_ENABLE;
79 else
80 val &= ~PCL_APP_LTSSM_ENABLE;
81 writel(val, priv->base + PCL_APP_READY_CTRL);
82}
83
84static void uniphier_pcie_init_rc(struct uniphier_pcie_priv *priv)
85{
86 u32 val;
87
88 /* use auxiliary power detection */
89 val = readl(priv->base + PCL_APP_PM0);
90 val |= PCL_SYS_AUX_PWR_DET;
91 writel(val, priv->base + PCL_APP_PM0);
92
93 /* assert PERST# */
94 val = readl(priv->base + PCL_PINCTRL0);
95 val &= ~(PCL_PERST_NOE_REGVAL | PCL_PERST_OUT_REGVAL
96 | PCL_PERST_PLDN_REGVAL);
97 val |= PCL_PERST_NOE_REGEN | PCL_PERST_OUT_REGEN
98 | PCL_PERST_PLDN_REGEN;
99 writel(val, priv->base + PCL_PINCTRL0);
100
101 uniphier_pcie_ltssm_enable(priv, false);
102
103 usleep_range(100000, 200000);
104
105 /* deassert PERST# */
106 val = readl(priv->base + PCL_PINCTRL0);
107 val |= PCL_PERST_OUT_REGVAL | PCL_PERST_OUT_REGEN;
108 writel(val, priv->base + PCL_PINCTRL0);
109}
110
111static int uniphier_pcie_wait_rc(struct uniphier_pcie_priv *priv)
112{
113 u32 status;
114 int ret;
115
116 /* wait PIPE clock */
117 ret = readl_poll_timeout(priv->base + PCL_PIPEMON, status,
118 status & PCL_PCLK_ALIVE, 100000, 1000000);
119 if (ret) {
120 dev_err(priv->pci.dev,
121 "Failed to initialize controller in RC mode\n");
122 return ret;
123 }
124
125 return 0;
126}
127
128static int uniphier_pcie_link_up(struct dw_pcie *pci)
129{
130 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
131 u32 val, mask;
132
133 val = readl(priv->base + PCL_STATUS_LINK);
134 mask = PCL_RDLH_LINK_UP | PCL_XMLH_LINK_UP;
135
136 return (val & mask) == mask;
137}
138
139static int uniphier_pcie_establish_link(struct dw_pcie *pci)
140{
141 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
142
143 if (dw_pcie_link_up(pci))
144 return 0;
145
146 uniphier_pcie_ltssm_enable(priv, true);
147
148 return dw_pcie_wait_for_link(pci);
149}
150
151static void uniphier_pcie_stop_link(struct dw_pcie *pci)
152{
153 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
154
155 uniphier_pcie_ltssm_enable(priv, false);
156}
157
158static void uniphier_pcie_irq_enable(struct uniphier_pcie_priv *priv)
159{
160 writel(PCL_RCV_INT_ALL_ENABLE, priv->base + PCL_RCV_INT);
161 writel(PCL_RCV_INTX_ALL_ENABLE, priv->base + PCL_RCV_INTX);
162}
163
164static void uniphier_pcie_irq_disable(struct uniphier_pcie_priv *priv)
165{
166 writel(0, priv->base + PCL_RCV_INT);
167 writel(0, priv->base + PCL_RCV_INTX);
168}
169
170static void uniphier_pcie_irq_ack(struct irq_data *d)
171{
172 struct pcie_port *pp = irq_data_get_irq_chip_data(d);
173 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
174 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
175 u32 val;
176
177 val = readl(priv->base + PCL_RCV_INTX);
178 val &= ~PCL_RCV_INTX_ALL_STATUS;
179 val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
180 writel(val, priv->base + PCL_RCV_INTX);
181}
182
183static void uniphier_pcie_irq_mask(struct irq_data *d)
184{
185 struct pcie_port *pp = irq_data_get_irq_chip_data(d);
186 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
187 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
188 u32 val;
189
190 val = readl(priv->base + PCL_RCV_INTX);
191 val &= ~PCL_RCV_INTX_ALL_MASK;
192 val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
193 writel(val, priv->base + PCL_RCV_INTX);
194}
195
196static void uniphier_pcie_irq_unmask(struct irq_data *d)
197{
198 struct pcie_port *pp = irq_data_get_irq_chip_data(d);
199 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
200 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
201 u32 val;
202
203 val = readl(priv->base + PCL_RCV_INTX);
204 val &= ~PCL_RCV_INTX_ALL_MASK;
205 val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
206 writel(val, priv->base + PCL_RCV_INTX);
207}
208
209static struct irq_chip uniphier_pcie_irq_chip = {
210 .name = "PCI",
211 .irq_ack = uniphier_pcie_irq_ack,
212 .irq_mask = uniphier_pcie_irq_mask,
213 .irq_unmask = uniphier_pcie_irq_unmask,
214};
215
216static int uniphier_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
217 irq_hw_number_t hwirq)
218{
219 irq_set_chip_and_handler(irq, &uniphier_pcie_irq_chip,
220 handle_level_irq);
221 irq_set_chip_data(irq, domain->host_data);
222
223 return 0;
224}
225
226static const struct irq_domain_ops uniphier_intx_domain_ops = {
227 .map = uniphier_pcie_intx_map,
228};
229
230static void uniphier_pcie_irq_handler(struct irq_desc *desc)
231{
232 struct pcie_port *pp = irq_desc_get_handler_data(desc);
233 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
234 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
235 struct irq_chip *chip = irq_desc_get_chip(desc);
236 unsigned long reg;
237 u32 val, bit, virq;
238
239 /* INT for debug */
240 val = readl(priv->base + PCL_RCV_INT);
241
242 if (val & PCL_CFG_BW_MGT_STATUS)
243 dev_dbg(pci->dev, "Link Bandwidth Management Event\n");
244 if (val & PCL_CFG_LINK_AUTO_BW_STATUS)
245 dev_dbg(pci->dev, "Link Autonomous Bandwidth Event\n");
246 if (val & PCL_CFG_AER_RC_ERR_MSI_STATUS)
247 dev_dbg(pci->dev, "Root Error\n");
248 if (val & PCL_CFG_PME_MSI_STATUS)
249 dev_dbg(pci->dev, "PME Interrupt\n");
250
251 writel(val, priv->base + PCL_RCV_INT);
252
253 /* INTx */
254 chained_irq_enter(chip, desc);
255
256 val = readl(priv->base + PCL_RCV_INTX);
257 reg = FIELD_GET(PCL_RCV_INTX_ALL_STATUS, val);
258
259 for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
260 virq = irq_linear_revmap(priv->legacy_irq_domain, bit);
261 generic_handle_irq(virq);
262 }
263
264 chained_irq_exit(chip, desc);
265}
266
267static int uniphier_pcie_config_legacy_irq(struct pcie_port *pp)
268{
269 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
270 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
271 struct device_node *np = pci->dev->of_node;
272 struct device_node *np_intc;
273
274 np_intc = of_get_child_by_name(np, "legacy-interrupt-controller");
275 if (!np_intc) {
276 dev_err(pci->dev, "Failed to get legacy-interrupt-controller node\n");
277 return -EINVAL;
278 }
279
280 pp->irq = irq_of_parse_and_map(np_intc, 0);
281 if (!pp->irq) {
282 dev_err(pci->dev, "Failed to get an IRQ entry in legacy-interrupt-controller\n");
283 return -EINVAL;
284 }
285
286 priv->legacy_irq_domain = irq_domain_add_linear(np_intc, PCI_NUM_INTX,
287 &uniphier_intx_domain_ops, pp);
288 if (!priv->legacy_irq_domain) {
289 dev_err(pci->dev, "Failed to get INTx domain\n");
290 return -ENODEV;
291 }
292
293 irq_set_chained_handler_and_data(pp->irq, uniphier_pcie_irq_handler,
294 pp);
295
296 return 0;
297}
298
299static int uniphier_pcie_host_init(struct pcie_port *pp)
300{
301 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
302 struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
303 int ret;
304
305 ret = uniphier_pcie_config_legacy_irq(pp);
306 if (ret)
307 return ret;
308
309 uniphier_pcie_irq_enable(priv);
310
311 dw_pcie_setup_rc(pp);
312 ret = uniphier_pcie_establish_link(pci);
313 if (ret)
314 return ret;
315
316 if (IS_ENABLED(CONFIG_PCI_MSI))
317 dw_pcie_msi_init(pp);
318
319 return 0;
320}
321
322static const struct dw_pcie_host_ops uniphier_pcie_host_ops = {
323 .host_init = uniphier_pcie_host_init,
324};
325
326static int uniphier_add_pcie_port(struct uniphier_pcie_priv *priv,
327 struct platform_device *pdev)
328{
329 struct dw_pcie *pci = &priv->pci;
330 struct pcie_port *pp = &pci->pp;
331 struct device *dev = &pdev->dev;
332 int ret;
333
334 pp->ops = &uniphier_pcie_host_ops;
335
336 if (IS_ENABLED(CONFIG_PCI_MSI)) {
337 pp->msi_irq = platform_get_irq_byname(pdev, "msi");
338 if (pp->msi_irq < 0)
339 return pp->msi_irq;
340 }
341
342 ret = dw_pcie_host_init(pp);
343 if (ret) {
344 dev_err(dev, "Failed to initialize host (%d)\n", ret);
345 return ret;
346 }
347
348 return 0;
349}
350
351static int uniphier_pcie_host_enable(struct uniphier_pcie_priv *priv)
352{
353 int ret;
354
355 ret = clk_prepare_enable(priv->clk);
356 if (ret)
357 return ret;
358
359 ret = reset_control_deassert(priv->rst);
360 if (ret)
361 goto out_clk_disable;
362
363 uniphier_pcie_init_rc(priv);
364
365 ret = phy_init(priv->phy);
366 if (ret)
367 goto out_rst_assert;
368
369 ret = uniphier_pcie_wait_rc(priv);
370 if (ret)
371 goto out_phy_exit;
372
373 return 0;
374
375out_phy_exit:
376 phy_exit(priv->phy);
377out_rst_assert:
378 reset_control_assert(priv->rst);
379out_clk_disable:
380 clk_disable_unprepare(priv->clk);
381
382 return ret;
383}
384
385static void uniphier_pcie_host_disable(struct uniphier_pcie_priv *priv)
386{
387 uniphier_pcie_irq_disable(priv);
388 phy_exit(priv->phy);
389 reset_control_assert(priv->rst);
390 clk_disable_unprepare(priv->clk);
391}
392
393static const struct dw_pcie_ops dw_pcie_ops = {
394 .start_link = uniphier_pcie_establish_link,
395 .stop_link = uniphier_pcie_stop_link,
396 .link_up = uniphier_pcie_link_up,
397};
398
399static int uniphier_pcie_probe(struct platform_device *pdev)
400{
401 struct device *dev = &pdev->dev;
402 struct uniphier_pcie_priv *priv;
403 struct resource *res;
404 int ret;
405
406 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
407 if (!priv)
408 return -ENOMEM;
409
410 priv->pci.dev = dev;
411 priv->pci.ops = &dw_pcie_ops;
412
413 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
414 priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res);
415 if (IS_ERR(priv->pci.dbi_base))
416 return PTR_ERR(priv->pci.dbi_base);
417
418 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "link");
419 priv->base = devm_ioremap_resource(dev, res);
420 if (IS_ERR(priv->base))
421 return PTR_ERR(priv->base);
422
423 priv->clk = devm_clk_get(dev, NULL);
424 if (IS_ERR(priv->clk))
425 return PTR_ERR(priv->clk);
426
427 priv->rst = devm_reset_control_get_shared(dev, NULL);
428 if (IS_ERR(priv->rst))
429 return PTR_ERR(priv->rst);
430
431 priv->phy = devm_phy_optional_get(dev, "pcie-phy");
432 if (IS_ERR(priv->phy))
433 return PTR_ERR(priv->phy);
434
435 platform_set_drvdata(pdev, priv);
436
437 ret = uniphier_pcie_host_enable(priv);
438 if (ret)
439 return ret;
440
441 return uniphier_add_pcie_port(priv, pdev);
442}
443
444static int uniphier_pcie_remove(struct platform_device *pdev)
445{
446 struct uniphier_pcie_priv *priv = platform_get_drvdata(pdev);
447
448 uniphier_pcie_host_disable(priv);
449
450 return 0;
451}
452
453static const struct of_device_id uniphier_pcie_match[] = {
454 { .compatible = "socionext,uniphier-pcie", },
455 { /* sentinel */ },
456};
457MODULE_DEVICE_TABLE(of, uniphier_pcie_match);
458
459static struct platform_driver uniphier_pcie_driver = {
460 .probe = uniphier_pcie_probe,
461 .remove = uniphier_pcie_remove,
462 .driver = {
463 .name = "uniphier-pcie",
464 .of_match_table = uniphier_pcie_match,
465 },
466};
467builtin_platform_driver(uniphier_pcie_driver);
468
469MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
470MODULE_DESCRIPTION("UniPhier PCIe host controller driver");
471MODULE_LICENSE("GPL v2");