Skip to contentSkip to conversation

PCI: Add Intel PCIe Driver and respective dt-binding yaml file

PATCH Superseded Dilip Kota 2 participants 6 messages Nov 20, 2019 – Nov 21, 2019

Subsystems (6)

v8 of 11 Superseded Latest is v11 →

lore
Share & tools
lore

Dilip Kota

author
#0 lore raw

v8 cover PCI: Add Intel PCIe Driver and respective dt-binding yaml file

Intel PCIe is Synopsys based controller. Intel PCIe driver uses DesignWare PCIe framework for host initialization and register configurations.

Dilip Kota (3):
dt-bindings: PCI: intel: Add YAML schemas for the PCIe RC controller
dwc: PCI: intel: PCIe RC controller driver
PCI: artpec6: Configure FTS with dwc helper function

 .../devicetree/bindings/pci/intel-gw-pcie.yaml     | 138 ++++++
 drivers/pci/controller/dwc/Kconfig                 |  10 +
 drivers/pci/controller/dwc/Makefile                |   1 +
 drivers/pci/controller/dwc/pcie-artpec6.c          |   8 +-
 drivers/pci/controller/dwc/pcie-designware.c       |  57 +++
 drivers/pci/controller/dwc/pcie-designware.h       |  12 +
 drivers/pci/controller/dwc/pcie-intel-gw.c         | 545 +++++++++++++++++++++
 include/uapi/linux/pci_regs.h                      |   1 +
 8 files changed, 765 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-intel-gw.c
Signature · 1 line
2.11.0
author
#1 lore raw

PATCH v8 1/3 dt-bindings: PCI: intel: Add YAML schemas for the PCIe RC controller

Add YAML schemas for PCIe RC controller on Intel Gateway SoCs which is Synopsys DesignWare based PCIe core.

---
Changes on v8:
No change

Changes on v7:
No change

Changes on v6:
Add Reviewed-by: Rob Herring <[email protected]>

Changes on v5:
Add Reviewed-by Andrew Murray.
Add possible values and default value for max-link-speed. Remove $ref and add maximum and default for reset-assert-ms. Set true flag for linux,pci-domain.
Define maxItems for ranges and clock.
Define maximum for num-lanes.
Update required list:
Add #address-cells, #size-cells, #interrupt-cells. Remove num-lanes and linux,pci-domain.
Add required header files in example.
Remove status entry in example.

changes on v4:
Add "snps,dw-pcie" compatible.
Rename phy-names property value to pcie. And maximum and minimum values to num-lanes. Add ref for reset-assert-ms entry and update the
description for easy understanding.
Remove PCIe core interrupt entry.

changes on v3:
Add the appropriate License-Identifier
Rename intel,rst-interval to 'reset-assert-us'
Add additionalProperties: false
Rename phy-names to 'pciephy'
Remove the dtsi node split of SoC and board in the example Add #interrupt-cells = <1>; or else interrupt parsing will fail Name yaml file with compatible name

 .../devicetree/bindings/pci/intel-gw-pcie.yaml     | 138 +++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml
Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml new file +138 -0
new file mode 100644
index 000000000000..db605d8a387d
@@ -0,0 +1,138 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/intel-gw-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PCIe RC controller on Intel Gateway SoCs
+
+maintainers:
+  - Dilip Kota <[email protected]>
+
+properties:
+  compatible:
+    items:
+      - const: intel,lgm-pcie
+      - const: snps,dw-pcie
+
+  device_type:
+    const: pci
+
+  "#address-cells":
+    const: 3
+
+  "#size-cells":
+    const: 2
+
+  reg:
+    items:
+      - description: Controller control and status registers.
+      - description: PCIe configuration registers.
+      - description: Controller application registers.
+
+  reg-names:
+    items:
+      - const: dbi
+      - const: config
+      - const: app
+
+  ranges:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: pcie
+
+  reset-gpios:
+    maxItems: 1
+
+  linux,pci-domain: true
+
+  num-lanes:
+    maximum: 2
+    description: Number of lanes to use for this port.
+
+  '#interrupt-cells':
+    const: 1
+
+  interrupt-map-mask:
+    description: Standard PCI IRQ mapping properties.
+
+  interrupt-map:
+    description: Standard PCI IRQ mapping properties.
+
+  max-link-speed:
+    description: Specify PCI Gen for link capability.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [ 1, 2, 3, 4 ]
+      - default: 1
+
+  bus-range:
+    description: Range of bus numbers associated with this controller.
+
+  reset-assert-ms:
+    description: |
+      Delay after asserting reset to the PCIe device.
+    maximum: 500
+    default: 100
+
+required:
+  - compatible
+  - device_type
+  - "#address-cells"
+  - "#size-cells"
+  - reg
+  - reg-names
+  - ranges
+  - resets
+  - clocks
+  - phys
+  - phy-names
+  - reset-gpios
+  - '#interrupt-cells'
+  - interrupt-map
+  - interrupt-map-mask
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/clock/intel,lgm-clk.h>
+    pcie10: pcie@d0e00000 {
+      compatible = "intel,lgm-pcie", "snps,dw-pcie";
+      device_type = "pci";
+      #address-cells = <3>;
+      #size-cells = <2>;
+      reg = <0xd0e00000 0x1000>,
+            <0xd2000000 0x800000>,
+            <0xd0a41000 0x1000>;
+      reg-names = "dbi", "config", "app";
+      linux,pci-domain = <0>;
+      max-link-speed = <4>;
+      bus-range = <0x00 0x08>;
+      interrupt-parent = <&ioapic1>;
+      #interrupt-cells = <1>;
+      interrupt-map-mask = <0 0 0 0x7>;
+      interrupt-map = <0 0 0 1 &ioapic1 27 1>,
+                      <0 0 0 2 &ioapic1 28 1>,
+                      <0 0 0 3 &ioapic1 29 1>,
+                      <0 0 0 4 &ioapic1 30 1>;
+      ranges = <0x02000000 0 0xd4000000 0xd4000000 0 0x04000000>;
+      resets = <&rcu0 0x50 0>;
+      clocks = <&cgu0 LGM_GCLK_PCIE10>;
+      phys = <&cb0phy0>;
+      phy-names = "pcie";
+      reset-assert-ms = <500>;
+      reset-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+      num-lanes = <2>;
+    };
Signature · 1 line
2.11.0
author
#2 lore raw

PATCH v8 2/3 dwc: PCI: intel: PCIe RC controller driver

In reply to Dilip Kota

Add support to PCIe RC controller on Intel Gateway SoCs. PCIe controller is based of Synopsys DesignWare PCIe core.

Intel PCIe driver requires Upconfigure support, Fast Training Sequence and link speed configurations. So adding the respective helper functions in the PCIe DesignWare framework.
It also programs hardware autonomous speed during speed configuration so defining it in pci_regs.h.

---
Changes on v8:
Add Reviewed-by: Andy Shevchenko <[email protected]> Place INTEL_GW config in order in Makefile and Kconfig Follow offset, mask and value order in function arguments update reset-assert-ms dt property read to
ret = device_property_read_u32(...);
if (ret)
...
Changes on v7:

	Add Acked-by: Gustavo Pimentel <[email protected]>
	Remove unused header files.
	  #include <linux/interrupt.h>
	  #include <linux/of_irq.h>
	  #include <linux/of_pci.h>
	  #include <linux/of_platform.h>

Changes on v6:
Add Reviewed-by: Andrew Murray <[email protected]> Address review comments:
Remove extra space in Kconfig
Fix style indents in switch case
Apply mask for the n_fts argument in dw_pcie_link_set_n_fts()
to prevent the case of n_fts value having outside the mask bits
Update PORT_LOGIC_N_FTS to PORT_LOGIC_N_FTS_MASK Update BUS_IATU_OFFS to BUS_IATU_OFFSET
Update RST_INTRVL_DFT_MS to RESET_INTERVAL_MS
Reduce local variables in pcie_update_bits()
Remove blank lines
Remove extra paranthesis during readl_poll_timeout() call Add error handling for dw_pcie_find_capability() call Add blank line before dev_info() in probe()

Changes on v5:
Use new, old variables in pcie_update_bits()
Correct naming:
s/Designware/DesignWare
s/pcie/PCIe
s/pci/PCI
s/Hw/HW
Upconfig to Upconfigure
Remove extra lines after the intel_pcie_max_speed_setup() def. Use pcie_link_speed[] and remove enum for pcie gen. Remove dw_pcie_link_speed_change() def.
Remove "linux,pci-domain" parsing.
Remove 'id' variable in intel_pcie_port structure.
Remove extra spaces for lpp->link_gen =
Correct the offset of PCI_EXP_LNKCTL2_HASD to 0x0020. Remove programming of RCB and CCC bits in PCI_EXP_LCTL reg. Remove programming Slot clock cfg in PCI_EXP_LSTS reg. Update the comments at num_viewport setting.
Update the description in Kconfig.
Get PCIe cap offset from the registers using dw_pcie_find_capability() Define pcie_cap_ofst var in intel_pcie_port struct to store the same. Remove the PCIE_CAP_OFST macro.
Move intel_pcie_max_speed_setup() function to DesignWare framework,
defined as dw_pcie_link_set_max_speed()
Set EXPORT_SYMBOL_GPL for the newer functions defined in
pcie-designware.c

Changes on v4:
Rename the driver naming and description to
"PCIe RC controller on Intel Gateway SoCs".
Use PCIe core register macros defined in pci_regs.h
and remove respective local definitions.
Remove PCIe core interrupt handling.
Move PCIe link control speed change, upconfig and FTS. configuration functions to DesignWare framework.
Use of_pci_get_max_link_speed().
Mark dependency on X86 and COMPILE_TEST in Kconfig.
Remove lanes and add n_fts variables in intel_pcie_port structure. Rename rst_interval variable to rst_intrvl in intel_pcie_port structure. Remove intel_pcie_mem_iatu() as it is already perfomed in dw_setup_rc() Move sysfs attributes specific code to separate patch. Remove redundant error handling.
Reduce LoCs by doing variable initializations while declaration itself. Add extra line after closing parenthesis.
Move intel_pcie_ep_rst_init() out of get_resources()

changes on v3:
Rename PCIe app logic registers with PCIE_APP prefix. PCIE_IOP_CTRL configuration is not required. Remove respective code. Remove wrapper functions for clk enable/disable APIs.
Use platform_get_resource_byname() instead of
devm_platform_ioremap_resource() to be similar with DWC framework.
Rename phy name to "pciephy".
Modify debug message in msi_init() callback to be more specific. Remove map_irq() callback.
Enable the INTx interrupts at the time of PCIe initialization. Reduce memory fragmentation by using variable "struct dw_pcie pci"
instead of allocating memory.
Reduce the delay to 100us during enpoint initialization
intel_pcie_ep_rst_init().
Call dw_pcie_host_deinit() during remove() instead of directly
calling PCIe core APIs.
Rename "intel,rst-interval" to "reset-assert-ms".
Remove unused APP logic Interrupt bit macro definitions. Use dwc framework's dw_pcie_setup_rc() for PCIe host specific
configuration instead of redefining the same functionality in the driver.
Move the whole DT parsing specific code to intel_pcie_get_resources()

 drivers/pci/controller/dwc/Kconfig           |  10 +
 drivers/pci/controller/dwc/Makefile          |   1 +
 drivers/pci/controller/dwc/pcie-designware.c |  57 +++
 drivers/pci/controller/dwc/pcie-designware.h |  12 +
 drivers/pci/controller/dwc/pcie-intel-gw.c   | 545 +++++++++++++++++++++++++++
 include/uapi/linux/pci_regs.h                |   1 +
 6 files changed, 626 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-intel-gw.c
drivers/pci/controller/dwc/Kconfig +10 -0
index 0ba988b5b5bc..e580ae036d77 100644
@@ -209,6 +209,16 @@ config PCIE_ARTPEC6_EP
 	  Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
 	  endpoint mode. This uses the DesignWare core.
 
+config PCIE_INTEL_GW
+	bool "Intel Gateway PCIe host controller support"
+	depends on OF && (X86 || COMPILE_TEST)
+	select PCIE_DW_HOST
+	help
+	  Say 'Y' here to enable PCIe Host controller support on Intel
+	  Gateway SoCs.
+	  The PCIe controller uses the DesignWare core plus Intel-specific
+	  hardware wrappers.
+
 config PCIE_KIRIN
 	depends on OF && (ARM64 || COMPILE_TEST)
 	bool "HiSilicon Kirin series SoCs PCIe controllers"
drivers/pci/controller/dwc/Makefile +1 -0
index b30336181d46..901e20f2ea96 100644
@@ -12,6 +12,7 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o pci-layerscape-ep.o
 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
+obj-$(CONFIG_PCIE_INTEL_GW) += pcie-intel-gw.o
 obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o
 obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
 obj-$(CONFIG_PCI_MESON) += pci-meson.o
drivers/pci/controller/dwc/pcie-designware.c +57 -0

69 lines not on this page · raw message

drivers/pci/controller/dwc/pcie-designware.h +12 -0
index 5a18e94e52c8..3b0be5cd9235 100644
@@ -30,7 +30,12 @@
 #define LINK_WAIT_IATU			9
 
 /* Synopsys-specific PCIe configuration registers */
+#define PCIE_PORT_AFR			0x70C
+#define PORT_AFR_N_FTS_MASK		GENMASK(15, 8)
+#define PORT_AFR_CC_N_FTS_MASK		GENMASK(23, 16)
+
 #define PCIE_PORT_LINK_CONTROL		0x710
+#define PORT_LINK_DLL_LINK_EN		BIT(5)
 #define PORT_LINK_MODE_MASK		GENMASK(21, 16)
 #define PORT_LINK_MODE(n)		FIELD_PREP(PORT_LINK_MODE_MASK, n)
 #define PORT_LINK_MODE_1_LANES		PORT_LINK_MODE(0x1)
@@ -46,6 +51,7 @@
 #define PCIE_PORT_DEBUG1_LINK_IN_TRAINING	BIT(29)
 
 #define PCIE_LINK_WIDTH_SPEED_CONTROL	0x80C
+#define PORT_LOGIC_N_FTS_MASK		GENMASK(7, 0)
 #define PORT_LOGIC_SPEED_CHANGE		BIT(17)
 #define PORT_LOGIC_LINK_WIDTH_MASK	GENMASK(12, 8)
 #define PORT_LOGIC_LINK_WIDTH(n)	FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n)
@@ -60,6 +66,9 @@
 #define PCIE_MSI_INTR0_MASK		0x82C
 #define PCIE_MSI_INTR0_STATUS		0x830
 
+#define PCIE_PORT_MULTI_LANE_CTRL	0x8C0
+#define PORT_MLTI_UPCFG_SUPPORT		BIT(7)
+
 #define PCIE_ATU_VIEWPORT		0x900
 #define PCIE_ATU_REGION_INBOUND		BIT(31)
 #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);
 u32 dw_pcie_read_atu(struct dw_pcie *pci, u32 reg, size_t size);
 void dw_pcie_write_atu(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
 int dw_pcie_link_up(struct dw_pcie *pci);
+void dw_pcie_upconfig_setup(struct dw_pcie *pci);
+void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen);
+void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts);
 int dw_pcie_wait_for_link(struct dw_pcie *pci);
 void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
 			       int type, u64 cpu_addr, u64 pci_addr,
drivers/pci/controller/dwc/pcie-intel-gw.c new file +545 -0

545 lines not on this page · raw message

include/uapi/linux/pci_regs.h +1 -0
index 29d6e93fd15e..548e22e07a52 100644
@@ -673,6 +673,7 @@
 #define  PCI_EXP_LNKCTL2_TLS_8_0GT	0x0003 /* Supported Speed 8GT/s */
 #define  PCI_EXP_LNKCTL2_TLS_16_0GT	0x0004 /* Supported Speed 16GT/s */
 #define  PCI_EXP_LNKCTL2_TLS_32_0GT	0x0005 /* Supported Speed 32GT/s */
+#define  PCI_EXP_LNKCTL2_HASD		0x0020 /* HW Autonomous Speed Disable */
 #define PCI_EXP_LNKSTA2		50	/* Link Status 2 */
 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2	52	/* v2 endpoints with link end here */
 #define PCI_EXP_SLTCAP2		52	/* Slot Capabilities 2 */
Signature · 1 line
2.11.0
#3 lore raw

Re: [PATCH v8 2/3] dwc: PCI: intel: PCIe RC controller driver

Review

Quoted 11 lines · Dilip Kota

Add support to PCIe RC controller on Intel Gateway SoCs. PCIe controller is based of Synopsys DesignWare PCIe core.

Intel PCIe driver requires Upconfigure support, Fast Training Sequence and link speed configurations. So adding the respective helper functions in the PCIe DesignWare framework.
It also programs hardware autonomous speed during speed configuration so defining it in pci_regs.h.

(quoted diff) +2 -0
+static void pcie_app_wr_mask(struct intel_pcie_port *lpp,
+			     u32 ofs, u32 mask, u32 val)

It seems your editor is misconfigured. First line should be

static void pcie_app_wr_mask(struct intel_pcie_port *lpp, u32 ofs,

in case you would like to split it logically.

drivers/pci/controller/dwc/pcie-intel-gw.c line 118

Quoted 2 lines
drivers/pci/controller/dwc/pcie-intel-gw.c new file +2 -0
+static void pcie_rc_cfg_wr_mask(struct intel_pcie_port *lpp,
+				u32 ofs, u32 mask, u32 val)

Ditto.

drivers/pci/controller/dwc/pcie-intel-gw.c line 248

Quoted 1 line
drivers/pci/controller/dwc/pcie-intel-gw.c new file +1 -0
+	pcie_app_wr(lpp,  PCIE_APP_IRNCR, PCIE_APP_IRN_INT);

Extra white space.

Signature · 2 lines
With Best Regards,
Andy Shevchenko
author
#4 lore raw

Re: [PATCH v8 2/3] dwc: PCI: intel: PCIe RC controller driver

Quoted 15 lines · Andy Shevchenko

Review

Quoted 10 lines · Dilip Kota

Add support to PCIe RC controller on Intel Gateway SoCs. PCIe controller is based of Synopsys DesignWare PCIe core.

Intel PCIe driver requires Upconfigure support, Fast Training Sequence and link speed configurations. So adding the respective helper functions in the PCIe DesignWare framework.
It also programs hardware autonomous speed during speed configuration so defining it in pci_regs.h.

(quoted diff) +2 -0
+static void pcie_app_wr_mask(struct intel_pcie_port *lpp,
+			     u32 ofs, u32 mask, u32 val)

It seems your editor is misconfigured. First line should be

static void pcie_app_wr_mask(struct intel_pcie_port *lpp, u32 ofs,

Quoted 8 lines

in case you would like to split it logically.

drivers/pci/controller/dwc/pcie-intel-gw.c line 118

Quoted 2 lines
drivers/pci/controller/dwc/pcie-intel-gw.c new file +2 -0
+static void pcie_rc_cfg_wr_mask(struct intel_pcie_port *lpp,
+				u32 ofs, u32 mask, u32 val)

Ditto.

drivers/pci/controller/dwc/pcie-intel-gw.c line 248

Quoted 1 line
drivers/pci/controller/dwc/pcie-intel-gw.c new file +1 -0
+	pcie_app_wr(lpp,  PCIE_APP_IRNCR, PCIE_APP_IRN_INT);

Extra white space.

My bad, typo error. Will fix them all in the next patch version.

Regards,
Dilip

Quoted 1 line
author
#5 lore raw

PATCH v8 3/3 PCI: artpec6: Configure FTS with dwc helper function

In reply to Dilip Kota

Use DesignWare helper functions to configure Fast Training Sequence. Drop the respective code in the driver.

---
Changes on v8:
No change

Changes on v7:
No change

Changes on v6:

	Typo fix:s/DesugnWare/DesignWare
	Update 'Utilize DesignWare' --> 'Use DesignWare'
	Add Reviewed-by: Andrew Murray <[email protected]>
 drivers/pci/controller/dwc/pcie-artpec6.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/pci/controller/dwc/pcie-artpec6.c +1 -7
index d00252bd8fae..02d93b8c7942 100644
@@ -51,9 +51,6 @@ static const struct of_device_id artpec6_pcie_of_match[];
 #define ACK_N_FTS_MASK			GENMASK(15, 8)
 #define ACK_N_FTS(x)			(((x) << 8) & ACK_N_FTS_MASK)
 
-#define FAST_TRAINING_SEQ_MASK		GENMASK(7, 0)
-#define FAST_TRAINING_SEQ(x)		(((x) << 0) & FAST_TRAINING_SEQ_MASK)
-
 /* ARTPEC-6 specific registers */
 #define PCIECFG				0x18
 #define  PCIECFG_DBG_OEN		BIT(24)
@@ -313,10 +310,7 @@ static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie)
 	 * Set the Number of Fast Training Sequences that the core
 	 * advertises as its N_FTS during Gen2 or Gen3 link training.
 	 */
-	val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
-	val &= ~FAST_TRAINING_SEQ_MASK;
-	val |= FAST_TRAINING_SEQ(180);
-	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+	dw_pcie_link_set_n_fts(pci, 180);
 }
 
 static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
Signature · 1 line
2.11.0