History

Merge branch 'remotes/lorenzo/pci/dwc'

- Add intel-gw driver for PCIe host controller on Intel Gateway SoC (Dilip Kota) - Use shared DesignWare helpers to configure Fast Training Sequence (FTS) in artpec6 (Dilip Kota) * remotes/lorenzo/pci/dwc: PCI: artpec6: Configure FTS with dwc helper function PCI: dwc: intel: PCIe RC controller driver dt-bindings: PCI: intel: Add YAML schemas for the PCIe RC controller

Bjorn Helgaas committed 6 years ago

Commit 4c6a8fe2 parents 61d02c3 6fd622c8 files · +765 −7Browse files

Unified · Split

8 files
  1. Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml +138 −0
  2. drivers/pci/controller/dwc/Kconfig +11 −0
  3. drivers/pci/controller/dwc/Makefile +1 −0
  4. drivers/pci/controller/dwc/pcie-artpec6.c +1 −7
  5. drivers/pci/controller/dwc/pcie-designware.c +56 −0
  6. drivers/pci/controller/dwc/pcie-designware.h +12 −0
  7. drivers/pci/controller/dwc/pcie-intel-gw.c +545 −0
  8. include/uapi/linux/pci_regs.h +1 −0
Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml+138−0
@@ -0,0 +1,138 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/pci/intel-gw-pcie.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: PCIe RC controller on Intel Gateway SoCs
8+
9+maintainers:
10+ - Dilip Kota <eswara.kota@linux.intel.com>
11+
12+properties:
13+ compatible:
14+ items:
15+ - const: intel,lgm-pcie
16+ - const: snps,dw-pcie
17+
18+ device_type:
19+ const: pci
20+
21+ "#address-cells":
22+ const: 3
23+
24+ "#size-cells":
25+ const: 2
26+
27+ reg:
28+ items:
29+ - description: Controller control and status registers.
30+ - description: PCIe configuration registers.
31+ - description: Controller application registers.
32+
33+ reg-names:
34+ items:
35+ - const: dbi
36+ - const: config
37+ - const: app
38+
39+ ranges:
40+ maxItems: 1
41+
42+ resets:
43+ maxItems: 1
44+
45+ clocks:
46+ maxItems: 1
47+
48+ phys:
49+ maxItems: 1
50+
51+ phy-names:
52+ const: pcie
53+
54+ reset-gpios:
55+ maxItems: 1
56+
57+ linux,pci-domain: true
58+
59+ num-lanes:
60+ maximum: 2
61+ description: Number of lanes to use for this port.
62+
63+ '#interrupt-cells':
64+ const: 1
65+
66+ interrupt-map-mask:
67+ description: Standard PCI IRQ mapping properties.
68+
69+ interrupt-map:
70+ description: Standard PCI IRQ mapping properties.
71+
72+ max-link-speed:
73+ description: Specify PCI Gen for link capability.
74+ allOf:
75+ - $ref: /schemas/types.yaml#/definitions/uint32
76+ - enum: [ 1, 2, 3, 4 ]
77+ - default: 1
78+
79+ bus-range:
80+ description: Range of bus numbers associated with this controller.
81+
82+ reset-assert-ms:
83+ description: |
84+ Delay after asserting reset to the PCIe device.
85+ maximum: 500
86+ default: 100
87+
88+required:
89+ - compatible
90+ - device_type
91+ - "#address-cells"
92+ - "#size-cells"
93+ - reg
94+ - reg-names
95+ - ranges
96+ - resets
97+ - clocks
98+ - phys
99+ - phy-names
100+ - reset-gpios
101+ - '#interrupt-cells'
102+ - interrupt-map
103+ - interrupt-map-mask
104+
105+additionalProperties: false
106+
107+examples:
108+ - |
109+ #include <dt-bindings/gpio/gpio.h>
110+ #include <dt-bindings/clock/intel,lgm-clk.h>
111+ pcie10: pcie@d0e00000 {
112+ compatible = "intel,lgm-pcie", "snps,dw-pcie";
113+ device_type = "pci";
114+ #address-cells = <3>;
115+ #size-cells = <2>;
116+ reg = <0xd0e00000 0x1000>,
117+ <0xd2000000 0x800000>,
118+ <0xd0a41000 0x1000>;
119+ reg-names = "dbi", "config", "app";
120+ linux,pci-domain = <0>;
121+ max-link-speed = <4>;
122+ bus-range = <0x00 0x08>;
123+ interrupt-parent = <&ioapic1>;
124+ #interrupt-cells = <1>;
125+ interrupt-map-mask = <0 0 0 0x7>;
126+ interrupt-map = <0 0 0 1 &ioapic1 27 1>,
127+ <0 0 0 2 &ioapic1 28 1>,
128+ <0 0 0 3 &ioapic1 29 1>,
129+ <0 0 0 4 &ioapic1 30 1>;
130+ ranges = <0x02000000 0 0xd4000000 0xd4000000 0 0x04000000>;
131+ resets = <&rcu0 0x50 0>;
132+ clocks = <&cgu0 LGM_GCLK_PCIE10>;
133+ phys = <&cb0phy0>;
134+ phy-names = "pcie";
135+ reset-assert-ms = <500>;
136+ reset-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
137+ num-lanes = <2>;
138+ };
drivers/pci/controller/dwc/Kconfig+11−0
@@ -209,6 +209,17 @@ config PCIE_ARTPEC6_EP · 208 unmodified lines
209209 Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
210210 endpoint mode. This uses the DesignWare core.
211211
212+config PCIE_INTEL_GW
213+ bool "Intel Gateway PCIe host controller support"
214+ depends on OF && (X86 || COMPILE_TEST)
215+ depends on PCI_MSI_IRQ_DOMAIN
216+ select PCIE_DW_HOST
217+ help
218+ Say 'Y' here to enable PCIe Host controller support on Intel
219+ Gateway SoCs.
220+ The PCIe controller uses the DesignWare core plus Intel-specific
221+ hardware wrappers.
222+
212223 config PCIE_KIRIN
213224 depends on OF && (ARM64 || COMPILE_TEST)
214225 bool "HiSilicon Kirin series SoCs PCIe controllers"
drivers/pci/controller/dwc/Makefile+1−0
@@ -13,6 +13,7 @@ obj-$(CONFIG_PCI_LAYERSCAPE_EP) += pci-layerscape-ep.o · 12 unmodified lines
1313 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
1414 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
1515 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
16+obj-$(CONFIG_PCIE_INTEL_GW) += pcie-intel-gw.o
1617 obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o
1718 obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
1819 obj-$(CONFIG_PCI_MESON) += pci-meson.o
drivers/pci/controller/dwc/pcie-artpec6.c+1−7
@@ -51,9 +51,6 @@ static const struct of_device_id artpec6_pcie_of_match[]; · 50 unmodified lines
5151 #define ACK_N_FTS_MASK GENMASK(15, 8)
5252 #define ACK_N_FTS(x) (((x) << 8) & ACK_N_FTS_MASK)
5353
54−#define FAST_TRAINING_SEQ_MASK GENMASK(7, 0)
55−#define FAST_TRAINING_SEQ(x) (((x) << 0) & FAST_TRAINING_SEQ_MASK)
56−
5754 /* ARTPEC-6 specific registers */
5855 #define PCIECFG 0x18
5956 #define PCIECFG_DBG_OEN BIT(24)
@@ -313,10 +310,7 @@ static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie) · 253 unmodified lines
313310 * Set the Number of Fast Training Sequences that the core
314311 * advertises as its N_FTS during Gen2 or Gen3 link training.
315312 */
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);
313+ dw_pcie_link_set_n_fts(pci, 180);
320314 }
321315
322316 static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
drivers/pci/controller/dwc/pcie-designware.c+56−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/of.h>
1313 #include <linux/types.h>
1414
15+#include "../../pci.h"
1516 #include "pcie-designware.h"
1617
1718 /*
@@ -474,6 +475,61 @@ int dw_pcie_link_up(struct dw_pcie *pci) · 456 unmodified lines
474475 (!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING)));
475476 }
476477
478+void dw_pcie_upconfig_setup(struct dw_pcie *pci)
479+{
480+ u32 val;
481+
482+ val = dw_pcie_readl_dbi(pci, PCIE_PORT_MULTI_LANE_CTRL);
483+ val |= PORT_MLTI_UPCFG_SUPPORT;
484+ dw_pcie_writel_dbi(pci, PCIE_PORT_MULTI_LANE_CTRL, val);
485+}
486+EXPORT_SYMBOL_GPL(dw_pcie_upconfig_setup);
487+
488+void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen)
489+{
490+ u32 reg, val;
491+ u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
492+
493+ reg = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2);
494+ reg &= ~PCI_EXP_LNKCTL2_TLS;
495+
496+ switch (pcie_link_speed[link_gen]) {
497+ case PCIE_SPEED_2_5GT:
498+ reg |= PCI_EXP_LNKCTL2_TLS_2_5GT;
499+ break;
500+ case PCIE_SPEED_5_0GT:
501+ reg |= PCI_EXP_LNKCTL2_TLS_5_0GT;
502+ break;
503+ case PCIE_SPEED_8_0GT:
504+ reg |= PCI_EXP_LNKCTL2_TLS_8_0GT;
505+ break;
506+ case PCIE_SPEED_16_0GT:
507+ reg |= PCI_EXP_LNKCTL2_TLS_16_0GT;
508+ break;
509+ default:
510+ /* Use hardware capability */
511+ val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
512+ val = FIELD_GET(PCI_EXP_LNKCAP_SLS, val);
513+ reg &= ~PCI_EXP_LNKCTL2_HASD;
514+ reg |= FIELD_PREP(PCI_EXP_LNKCTL2_TLS, val);
515+ break;
516+ }
517+
518+ dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCTL2, reg);
519+}
520+EXPORT_SYMBOL_GPL(dw_pcie_link_set_max_speed);
521+
522+void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts)
523+{
524+ u32 val;
525+
526+ val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
527+ val &= ~PORT_LOGIC_N_FTS_MASK;
528+ val |= n_fts & PORT_LOGIC_N_FTS_MASK;
529+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
530+}
531+EXPORT_SYMBOL_GPL(dw_pcie_link_set_n_fts);
532+
477533 static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)
478534 {
479535 u32 val;
drivers/pci/controller/dwc/pcie-designware.h+12−0
@@ -30,7 +30,12 @@ · 29 unmodified lines
3030 #define LINK_WAIT_IATU 9
3131
3232 /* Synopsys-specific PCIe configuration registers */
33+#define PCIE_PORT_AFR 0x70C
34+#define PORT_AFR_N_FTS_MASK GENMASK(15, 8)
35+#define PORT_AFR_CC_N_FTS_MASK GENMASK(23, 16)
36+
3337 #define PCIE_PORT_LINK_CONTROL 0x710
38+#define PORT_LINK_DLL_LINK_EN BIT(5)
3439 #define PORT_LINK_MODE_MASK GENMASK(21, 16)
3540 #define PORT_LINK_MODE(n) FIELD_PREP(PORT_LINK_MODE_MASK, n)
3641 #define PORT_LINK_MODE_1_LANES PORT_LINK_MODE(0x1)
@@ -46,6 +51,7 @@ · 9 unmodified lines
4651 #define PCIE_PORT_DEBUG1_LINK_IN_TRAINING BIT(29)
4752
4853 #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
54+#define PORT_LOGIC_N_FTS_MASK GENMASK(7, 0)
4955 #define PORT_LOGIC_SPEED_CHANGE BIT(17)
5056 #define PORT_LOGIC_LINK_WIDTH_MASK GENMASK(12, 8)
5157 #define PORT_LOGIC_LINK_WIDTH(n) FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n)
@@ -60,6 +66,9 @@ · 8 unmodified lines
6066 #define PCIE_MSI_INTR0_MASK 0x82C
6167 #define PCIE_MSI_INTR0_STATUS 0x830
6268
69+#define PCIE_PORT_MULTI_LANE_CTRL 0x8C0
70+#define PORT_MLTI_UPCFG_SUPPORT BIT(7)
71+
6372 #define PCIE_ATU_VIEWPORT 0x900
6473 #define PCIE_ATU_REGION_INBOUND BIT(31)
6574 #define PCIE_ATU_REGION_OUTBOUND 0
@@ -273,6 +282,9 @@ void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val); · 207 unmodified lines
273282 u32 dw_pcie_read_atu(struct dw_pcie *pci, u32 reg, size_t size);
274283 void dw_pcie_write_atu(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
275284 int dw_pcie_link_up(struct dw_pcie *pci);
285+void dw_pcie_upconfig_setup(struct dw_pcie *pci);
286+void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen);
287+void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts);
276288 int dw_pcie_wait_for_link(struct dw_pcie *pci);
277289 void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
278290 int type, u64 cpu_addr, u64 pci_addr,
drivers/pci/controller/dwc/pcie-intel-gw.c+545−0
@@ -0,0 +1,545 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * PCIe host controller driver for Intel Gateway SoCs
4+ *
5+ * Copyright (c) 2019 Intel Corporation.
6+ */
7+
8+#include <linux/bitfield.h>
9+#include <linux/clk.h>
10+#include <linux/gpio/consumer.h>
11+#include <linux/iopoll.h>
12+#include <linux/pci_regs.h>
13+#include <linux/phy/phy.h>
14+#include <linux/platform_device.h>
15+#include <linux/reset.h>
16+
17+#include "../../pci.h"
18+#include "pcie-designware.h"
19+
20+#define PORT_AFR_N_FTS_GEN12_DFT (SZ_128 - 1)
21+#define PORT_AFR_N_FTS_GEN3 180
22+#define PORT_AFR_N_FTS_GEN4 196
23+
24+/* PCIe Application logic Registers */
25+#define PCIE_APP_CCR 0x10
26+#define PCIE_APP_CCR_LTSSM_ENABLE BIT(0)
27+
28+#define PCIE_APP_MSG_CR 0x30
29+#define PCIE_APP_MSG_XMT_PM_TURNOFF BIT(0)
30+
31+#define PCIE_APP_PMC 0x44
32+#define PCIE_APP_PMC_IN_L2 BIT(20)
33+
34+#define PCIE_APP_IRNEN 0xF4
35+#define PCIE_APP_IRNCR 0xF8
36+#define PCIE_APP_IRN_AER_REPORT BIT(0)
37+#define PCIE_APP_IRN_PME BIT(2)
38+#define PCIE_APP_IRN_RX_VDM_MSG BIT(4)
39+#define PCIE_APP_IRN_PM_TO_ACK BIT(9)
40+#define PCIE_APP_IRN_LINK_AUTO_BW_STAT BIT(11)
41+#define PCIE_APP_IRN_BW_MGT BIT(12)
42+#define PCIE_APP_IRN_MSG_LTR BIT(18)
43+#define PCIE_APP_IRN_SYS_ERR_RC BIT(29)
44+#define PCIE_APP_INTX_OFST 12
45+
46+#define PCIE_APP_IRN_INT \
47+ (PCIE_APP_IRN_AER_REPORT | PCIE_APP_IRN_PME | \
48+ PCIE_APP_IRN_RX_VDM_MSG | PCIE_APP_IRN_SYS_ERR_RC | \
49+ PCIE_APP_IRN_PM_TO_ACK | PCIE_APP_IRN_MSG_LTR | \
50+ PCIE_APP_IRN_BW_MGT | PCIE_APP_IRN_LINK_AUTO_BW_STAT | \
51+ (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTA) | \
52+ (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTB) | \
53+ (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTC) | \
54+ (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTD))
55+
56+#define BUS_IATU_OFFSET SZ_256M
57+#define RESET_INTERVAL_MS 100
58+
59+struct intel_pcie_soc {
60+ unsigned int pcie_ver;
61+ unsigned int pcie_atu_offset;
62+ u32 num_viewport;
63+};
64+
65+struct intel_pcie_port {
66+ struct dw_pcie pci;
67+ void __iomem *app_base;
68+ struct gpio_desc *reset_gpio;
69+ u32 rst_intrvl;
70+ u32 max_speed;
71+ u32 link_gen;
72+ u32 max_width;
73+ u32 n_fts;
74+ struct clk *core_clk;
75+ struct reset_control *core_rst;
76+ struct phy *phy;
77+ u8 pcie_cap_ofst;
78+};
79+
80+static void pcie_update_bits(void __iomem *base, u32 ofs, u32 mask, u32 val)
81+{
82+ u32 old;
83+
84+ old = readl(base + ofs);
85+ val = (old & ~mask) | (val & mask);
86+
87+ if (val != old)
88+ writel(val, base + ofs);
89+}
90+
91+static inline u32 pcie_app_rd(struct intel_pcie_port *lpp, u32 ofs)
92+{
93+ return readl(lpp->app_base + ofs);
94+}
95+
96+static inline void pcie_app_wr(struct intel_pcie_port *lpp, u32 ofs, u32 val)
97+{
98+ writel(val, lpp->app_base + ofs);
99+}
100+
101+static void pcie_app_wr_mask(struct intel_pcie_port *lpp, u32 ofs,
102+ u32 mask, u32 val)
103+{
104+ pcie_update_bits(lpp->app_base, ofs, mask, val);
105+}
106+
107+static inline u32 pcie_rc_cfg_rd(struct intel_pcie_port *lpp, u32 ofs)
108+{
109+ return dw_pcie_readl_dbi(&lpp->pci, ofs);
110+}
111+
112+static inline void pcie_rc_cfg_wr(struct intel_pcie_port *lpp, u32 ofs, u32 val)
113+{
114+ dw_pcie_writel_dbi(&lpp->pci, ofs, val);
115+}
116+
117+static void pcie_rc_cfg_wr_mask(struct intel_pcie_port *lpp, u32 ofs,
118+ u32 mask, u32 val)
119+{
120+ pcie_update_bits(lpp->pci.dbi_base, ofs, mask, val);
121+}
122+
123+static void intel_pcie_ltssm_enable(struct intel_pcie_port *lpp)
124+{
125+ pcie_app_wr_mask(lpp, PCIE_APP_CCR, PCIE_APP_CCR_LTSSM_ENABLE,
126+ PCIE_APP_CCR_LTSSM_ENABLE);
127+}
128+
129+static void intel_pcie_ltssm_disable(struct intel_pcie_port *lpp)
130+{
131+ pcie_app_wr_mask(lpp, PCIE_APP_CCR, PCIE_APP_CCR_LTSSM_ENABLE, 0);
132+}
133+
134+static void intel_pcie_link_setup(struct intel_pcie_port *lpp)
135+{
136+ u32 val;
137+ u8 offset = lpp->pcie_cap_ofst;
138+
139+ val = pcie_rc_cfg_rd(lpp, offset + PCI_EXP_LNKCAP);
140+ lpp->max_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, val);
141+ lpp->max_width = FIELD_GET(PCI_EXP_LNKCAP_MLW, val);
142+
143+ val = pcie_rc_cfg_rd(lpp, offset + PCI_EXP_LNKCTL);
144+
145+ val &= ~(PCI_EXP_LNKCTL_LD | PCI_EXP_LNKCTL_ASPMC);
146+ pcie_rc_cfg_wr(lpp, offset + PCI_EXP_LNKCTL, val);
147+}
148+
149+static void intel_pcie_port_logic_setup(struct intel_pcie_port *lpp)
150+{
151+ u32 val, mask;
152+
153+ switch (pcie_link_speed[lpp->max_speed]) {
154+ case PCIE_SPEED_8_0GT:
155+ lpp->n_fts = PORT_AFR_N_FTS_GEN3;
156+ break;
157+ case PCIE_SPEED_16_0GT:
158+ lpp->n_fts = PORT_AFR_N_FTS_GEN4;
159+ break;
160+ default:
161+ lpp->n_fts = PORT_AFR_N_FTS_GEN12_DFT;
162+ break;
163+ }
164+
165+ mask = PORT_AFR_N_FTS_MASK | PORT_AFR_CC_N_FTS_MASK;
166+ val = FIELD_PREP(PORT_AFR_N_FTS_MASK, lpp->n_fts) |
167+ FIELD_PREP(PORT_AFR_CC_N_FTS_MASK, lpp->n_fts);
168+ pcie_rc_cfg_wr_mask(lpp, PCIE_PORT_AFR, mask, val);
169+
170+ /* Port Link Control Register */
171+ pcie_rc_cfg_wr_mask(lpp, PCIE_PORT_LINK_CONTROL, PORT_LINK_DLL_LINK_EN,
172+ PORT_LINK_DLL_LINK_EN);
173+}
174+
175+static void intel_pcie_rc_setup(struct intel_pcie_port *lpp)
176+{
177+ intel_pcie_ltssm_disable(lpp);
178+ intel_pcie_link_setup(lpp);
179+ dw_pcie_setup_rc(&lpp->pci.pp);
180+ dw_pcie_upconfig_setup(&lpp->pci);
181+ intel_pcie_port_logic_setup(lpp);
182+ dw_pcie_link_set_max_speed(&lpp->pci, lpp->link_gen);
183+ dw_pcie_link_set_n_fts(&lpp->pci, lpp->n_fts);
184+}
185+
186+static int intel_pcie_ep_rst_init(struct intel_pcie_port *lpp)
187+{
188+ struct device *dev = lpp->pci.dev;
189+ int ret;
190+
191+ lpp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
192+ if (IS_ERR(lpp->reset_gpio)) {
193+ ret = PTR_ERR(lpp->reset_gpio);
194+ if (ret != -EPROBE_DEFER)
195+ dev_err(dev, "Failed to request PCIe GPIO: %d\n", ret);
196+ return ret;
197+ }
198+
199+ /* Make initial reset last for 100us */
200+ usleep_range(100, 200);
201+
202+ return 0;
203+}
204+
205+static void intel_pcie_core_rst_assert(struct intel_pcie_port *lpp)
206+{
207+ reset_control_assert(lpp->core_rst);
208+}
209+
210+static void intel_pcie_core_rst_deassert(struct intel_pcie_port *lpp)
211+{
212+ /*
213+ * One micro-second delay to make sure the reset pulse
214+ * wide enough so that core reset is clean.
215+ */
216+ udelay(1);
217+ reset_control_deassert(lpp->core_rst);
218+
219+ /*
220+ * Some SoC core reset also reset PHY, more delay needed
221+ * to make sure the reset process is done.
222+ */
223+ usleep_range(1000, 2000);
224+}
225+
226+static void intel_pcie_device_rst_assert(struct intel_pcie_port *lpp)
227+{
228+ gpiod_set_value_cansleep(lpp->reset_gpio, 1);
229+}
230+
231+static void intel_pcie_device_rst_deassert(struct intel_pcie_port *lpp)
232+{
233+ msleep(lpp->rst_intrvl);
234+ gpiod_set_value_cansleep(lpp->reset_gpio, 0);
235+}
236+
237+static int intel_pcie_app_logic_setup(struct intel_pcie_port *lpp)
238+{
239+ intel_pcie_device_rst_deassert(lpp);
240+ intel_pcie_ltssm_enable(lpp);
241+
242+ return dw_pcie_wait_for_link(&lpp->pci);
243+}
244+
245+static void intel_pcie_core_irq_disable(struct intel_pcie_port *lpp)
246+{
247+ pcie_app_wr(lpp, PCIE_APP_IRNEN, 0);
248+ pcie_app_wr(lpp, PCIE_APP_IRNCR, PCIE_APP_IRN_INT);
249+}
250+
251+static int intel_pcie_get_resources(struct platform_device *pdev)
252+{
253+ struct intel_pcie_port *lpp = platform_get_drvdata(pdev);
254+ struct dw_pcie *pci = &lpp->pci;
255+ struct device *dev = pci->dev;
256+ struct resource *res;
257+ int ret;
258+
259+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
260+ pci->dbi_base = devm_ioremap_resource(dev, res);
261+ if (IS_ERR(pci->dbi_base))
262+ return PTR_ERR(pci->dbi_base);
263+
264+ lpp->core_clk = devm_clk_get(dev, NULL);
265+ if (IS_ERR(lpp->core_clk)) {
266+ ret = PTR_ERR(lpp->core_clk);
267+ if (ret != -EPROBE_DEFER)
268+ dev_err(dev, "Failed to get clks: %d\n", ret);
269+ return ret;
270+ }
271+
272+ lpp->core_rst = devm_reset_control_get(dev, NULL);
273+ if (IS_ERR(lpp->core_rst)) {
274+ ret = PTR_ERR(lpp->core_rst);
275+ if (ret != -EPROBE_DEFER)
276+ dev_err(dev, "Failed to get resets: %d\n", ret);
277+ return ret;
278+ }
279+
280+ ret = device_property_match_string(dev, "device_type", "pci");
281+ if (ret) {
282+ dev_err(dev, "Failed to find pci device type: %d\n", ret);
283+ return ret;
284+ }
285+
286+ ret = device_property_read_u32(dev, "reset-assert-ms",
287+ &lpp->rst_intrvl);
288+ if (ret)
289+ lpp->rst_intrvl = RESET_INTERVAL_MS;
290+
291+ ret = of_pci_get_max_link_speed(dev->of_node);
292+ lpp->link_gen = ret < 0 ? 0 : ret;
293+
294+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "app");
295+ lpp->app_base = devm_ioremap_resource(dev, res);
296+ if (IS_ERR(lpp->app_base))
297+ return PTR_ERR(lpp->app_base);
298+
299+ lpp->phy = devm_phy_get(dev, "pcie");
300+ if (IS_ERR(lpp->phy)) {
301+ ret = PTR_ERR(lpp->phy);
302+ if (ret != -EPROBE_DEFER)
303+ dev_err(dev, "Couldn't get pcie-phy: %d\n", ret);
304+ return ret;
305+ }
306+
307+ return 0;
308+}
309+
310+static void intel_pcie_deinit_phy(struct intel_pcie_port *lpp)
311+{
312+ phy_exit(lpp->phy);
313+}
314+
315+static int intel_pcie_wait_l2(struct intel_pcie_port *lpp)
316+{
317+ u32 value;
318+ int ret;
319+
320+ if (pcie_link_speed[lpp->max_speed] < PCIE_SPEED_8_0GT)
321+ return 0;
322+
323+ /* Send PME_TURN_OFF message */
324+ pcie_app_wr_mask(lpp, PCIE_APP_MSG_CR, PCIE_APP_MSG_XMT_PM_TURNOFF,
325+ PCIE_APP_MSG_XMT_PM_TURNOFF);
326+
327+ /* Read PMC status and wait for falling into L2 link state */
328+ ret = readl_poll_timeout(lpp->app_base + PCIE_APP_PMC, value,
329+ value & PCIE_APP_PMC_IN_L2, 20,
330+ jiffies_to_usecs(5 * HZ));
331+ if (ret)
332+ dev_err(lpp->pci.dev, "PCIe link enter L2 timeout!\n");
333+
334+ return ret;
335+}
336+
337+static void intel_pcie_turn_off(struct intel_pcie_port *lpp)
338+{
339+ if (dw_pcie_link_up(&lpp->pci))
340+ intel_pcie_wait_l2(lpp);
341+
342+ /* Put endpoint device in reset state */
343+ intel_pcie_device_rst_assert(lpp);
344+ pcie_rc_cfg_wr_mask(lpp, PCI_COMMAND, PCI_COMMAND_MEMORY, 0);
345+}
346+
347+static int intel_pcie_host_setup(struct intel_pcie_port *lpp)
348+{
349+ struct device *dev = lpp->pci.dev;
350+ int ret;
351+
352+ intel_pcie_core_rst_assert(lpp);
353+ intel_pcie_device_rst_assert(lpp);
354+
355+ ret = phy_init(lpp->phy);
356+ if (ret)
357+ return ret;
358+
359+ intel_pcie_core_rst_deassert(lpp);
360+
361+ ret = clk_prepare_enable(lpp->core_clk);
362+ if (ret) {
363+ dev_err(lpp->pci.dev, "Core clock enable failed: %d\n", ret);
364+ goto clk_err;
365+ }
366+
367+ if (!lpp->pcie_cap_ofst) {
368+ ret = dw_pcie_find_capability(&lpp->pci, PCI_CAP_ID_EXP);
369+ if (!ret) {
370+ ret = -ENXIO;
371+ dev_err(dev, "Invalid PCIe capability offset\n");
372+ goto app_init_err;
373+ }
374+
375+ lpp->pcie_cap_ofst = ret;
376+ }
377+
378+ intel_pcie_rc_setup(lpp);
379+ ret = intel_pcie_app_logic_setup(lpp);
380+ if (ret)
381+ goto app_init_err;
382+
383+ /* Enable integrated interrupts */
384+ pcie_app_wr_mask(lpp, PCIE_APP_IRNEN, PCIE_APP_IRN_INT,
385+ PCIE_APP_IRN_INT);
386+
387+ return 0;
388+
389+app_init_err:
390+ clk_disable_unprepare(lpp->core_clk);
391+clk_err:
392+ intel_pcie_core_rst_assert(lpp);
393+ intel_pcie_deinit_phy(lpp);
394+
395+ return ret;
396+}
397+
398+static void __intel_pcie_remove(struct intel_pcie_port *lpp)
399+{
400+ intel_pcie_core_irq_disable(lpp);
401+ intel_pcie_turn_off(lpp);
402+ clk_disable_unprepare(lpp->core_clk);
403+ intel_pcie_core_rst_assert(lpp);
404+ intel_pcie_deinit_phy(lpp);
405+}
406+
407+static int intel_pcie_remove(struct platform_device *pdev)
408+{
409+ struct intel_pcie_port *lpp = platform_get_drvdata(pdev);
410+ struct pcie_port *pp = &lpp->pci.pp;
411+
412+ dw_pcie_host_deinit(pp);
413+ __intel_pcie_remove(lpp);
414+
415+ return 0;
416+}
417+
418+static int __maybe_unused intel_pcie_suspend_noirq(struct device *dev)
419+{
420+ struct intel_pcie_port *lpp = dev_get_drvdata(dev);
421+ int ret;
422+
423+ intel_pcie_core_irq_disable(lpp);
424+ ret = intel_pcie_wait_l2(lpp);
425+ if (ret)
426+ return ret;
427+
428+ intel_pcie_deinit_phy(lpp);
429+ clk_disable_unprepare(lpp->core_clk);
430+ return ret;
431+}
432+
433+static int __maybe_unused intel_pcie_resume_noirq(struct device *dev)
434+{
435+ struct intel_pcie_port *lpp = dev_get_drvdata(dev);
436+
437+ return intel_pcie_host_setup(lpp);
438+}
439+
440+static int intel_pcie_rc_init(struct pcie_port *pp)
441+{
442+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
443+ struct intel_pcie_port *lpp = dev_get_drvdata(pci->dev);
444+
445+ return intel_pcie_host_setup(lpp);
446+}
447+
448+/*
449+ * Dummy function so that DW core doesn't configure MSI
450+ */
451+static int intel_pcie_msi_init(struct pcie_port *pp)
452+{
453+ return 0;
454+}
455+
456+u64 intel_pcie_cpu_addr(struct dw_pcie *pcie, u64 cpu_addr)
457+{
458+ return cpu_addr + BUS_IATU_OFFSET;
459+}
460+
461+static const struct dw_pcie_ops intel_pcie_ops = {
462+ .cpu_addr_fixup = intel_pcie_cpu_addr,
463+};
464+
465+static const struct dw_pcie_host_ops intel_pcie_dw_ops = {
466+ .host_init = intel_pcie_rc_init,
467+ .msi_host_init = intel_pcie_msi_init,
468+};
469+
470+static const struct intel_pcie_soc pcie_data = {
471+ .pcie_ver = 0x520A,
472+ .pcie_atu_offset = 0xC0000,
473+ .num_viewport = 3,
474+};
475+
476+static int intel_pcie_probe(struct platform_device *pdev)
477+{
478+ const struct intel_pcie_soc *data;
479+ struct device *dev = &pdev->dev;
480+ struct intel_pcie_port *lpp;
481+ struct pcie_port *pp;
482+ struct dw_pcie *pci;
483+ int ret;
484+
485+ lpp = devm_kzalloc(dev, sizeof(*lpp), GFP_KERNEL);
486+ if (!lpp)
487+ return -ENOMEM;
488+
489+ platform_set_drvdata(pdev, lpp);
490+ pci = &lpp->pci;
491+ pci->dev = dev;
492+ pp = &pci->pp;
493+
494+ ret = intel_pcie_get_resources(pdev);
495+ if (ret)
496+ return ret;
497+
498+ ret = intel_pcie_ep_rst_init(lpp);
499+ if (ret)
500+ return ret;
501+
502+ data = device_get_match_data(dev);
503+ if (!data)
504+ return -ENODEV;
505+
506+ pci->ops = &intel_pcie_ops;
507+ pci->version = data->pcie_ver;
508+ pci->atu_base = pci->dbi_base + data->pcie_atu_offset;
509+ pp->ops = &intel_pcie_dw_ops;
510+
511+ ret = dw_pcie_host_init(pp);
512+ if (ret) {
513+ dev_err(dev, "Cannot initialize host\n");
514+ return ret;
515+ }
516+
517+ /*
518+ * Intel PCIe doesn't configure IO region, so set viewport
519+ * to not perform IO region access.
520+ */
521+ pci->num_viewport = data->num_viewport;
522+
523+ return 0;
524+}
525+
526+static const struct dev_pm_ops intel_pcie_pm_ops = {
527+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(intel_pcie_suspend_noirq,
528+ intel_pcie_resume_noirq)
529+};
530+
531+static const struct of_device_id of_intel_pcie_match[] = {
532+ { .compatible = "intel,lgm-pcie", .data = &pcie_data },
533+ {}
534+};
535+
536+static struct platform_driver intel_pcie_driver = {
537+ .probe = intel_pcie_probe,
538+ .remove = intel_pcie_remove,
539+ .driver = {
540+ .name = "intel-gw-pcie",
541+ .of_match_table = of_intel_pcie_match,
542+ .pm = &intel_pcie_pm_ops,
543+ },
544+};
545+builtin_platform_driver(intel_pcie_driver);
include/uapi/linux/pci_regs.h+1−0
@@ -676,6 +676,7 @@ · 675 unmodified lines
676676 #define PCI_EXP_LNKCTL2_TLS_32_0GT 0x0005 /* Supported Speed 32GT/s */
677677 #define PCI_EXP_LNKCTL2_ENTER_COMP 0x0010 /* Enter Compliance */
678678 #define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380 /* Transmit Margin */
679+#define PCI_EXP_LNKCTL2_HASD 0x0020 /* HW Autonomous Speed Disable */
679680 #define PCI_EXP_LNKSTA2 50 /* Link Status 2 */
680681 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52 /* v2 endpoints with link end here */
681682 #define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */