linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [”PATCH” v2 0/5] Asynchronous linkdown recovery
@ 2021-04-14 13:20 bpeled
  2021-04-14 13:20 ` [”PATCH” v2 1/5] PCI: armada8k: Disable LTSSM on link down interrupts bpeled
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: bpeled @ 2021-04-14 13:20 UTC (permalink / raw)
  To: thomas.petazzoni, lorenzo.pieralisi, bhelgaas
  Cc: linux-kernel, linux-arm-kernel, devicetree, linux-pci,
	sebastian.hesselbarth, gregory.clement, andrew, robh+dt, mw, jaz,
	kostap, nadavh, stefanc, oferh, Ben Peled

From: Ben Peled <bpeled@marvell.com>

The following patches implement the required procedure to handle and recover from asynchronous PCIE link down events on Armada SoCs.

The procedure is defined as the following:
1) Prevent new access to the PCI-E I/F by disabling the LTSSM
2) Flush all pending transaction/access to the PCI-E I/F
3) HW reset the PCIE end point device (based on board support)
4) Reset the PCIE MAC
5) Reinitialize the PCIE root complex and enable the LTSSM

The execution of this procedure is triggered by the PCIE RST_LINK_DOWN interrupt

v1 --> v2
- Add missing device reset to link-down handle

Ben Peled (5):
  PCI: armada8k: Disable LTSSM on link down interrupts
  PCI: armada8k: Add link-down handle
  dt-bindings: pci: add system controller and MAC reset bit to    
    Armada 7K/8K controller bindings
  arm64: dts: marvell: add pcie mac reset to pcie
  PCI: armada8k: add device reset to link-down handle

 Documentation/devicetree/bindings/pci/pci-armada8k.txt |   6 +
 arch/arm64/boot/dts/marvell/armada-cp11x.dtsi          |   7 ++
 drivers/pci/controller/dwc/pcie-armada8k.c             | 127 ++++++++++++++++++++
 3 files changed, 140 insertions(+)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [”PATCH” v2 1/5] PCI: armada8k: Disable LTSSM on link down interrupts
  2021-04-14 13:20 [”PATCH” v2 0/5] Asynchronous linkdown recovery bpeled
@ 2021-04-14 13:20 ` bpeled
  2021-12-09 11:28   ` Pali Rohár
  2021-04-14 13:20 ` [”PATCH” v2 2/5] PCI: armada8k: Add link-down handle bpeled
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: bpeled @ 2021-04-14 13:20 UTC (permalink / raw)
  To: thomas.petazzoni, lorenzo.pieralisi, bhelgaas
  Cc: linux-kernel, linux-arm-kernel, devicetree, linux-pci,
	sebastian.hesselbarth, gregory.clement, andrew, robh+dt, mw, jaz,
	kostap, nadavh, stefanc, oferh, Ben Peled, Marc St-Amand

From: Ben Peled <bpeled@marvell.com>

When a PCI link down condition is detected, the link training state
machine must be disabled immediately.

Signed-off-by: Marc St-Amand <mstamand@ciena.com>
Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
Signed-off-by: Ben Peled <bpeled@marvell.com>
---
 drivers/pci/controller/dwc/pcie-armada8k.c | 38 ++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
index 13901f3..b2278b1 100644
--- a/drivers/pci/controller/dwc/pcie-armada8k.c
+++ b/drivers/pci/controller/dwc/pcie-armada8k.c
@@ -54,6 +54,10 @@ struct armada8k_pcie {
 #define PCIE_INT_C_ASSERT_MASK		BIT(11)
 #define PCIE_INT_D_ASSERT_MASK		BIT(12)
 
+#define PCIE_GLOBAL_INT_CAUSE2_REG	(PCIE_VENDOR_REGS_OFFSET + 0x24)
+#define PCIE_GLOBAL_INT_MASK2_REG	(PCIE_VENDOR_REGS_OFFSET + 0x28)
+#define PCIE_INT2_PHY_RST_LINK_DOWN	BIT(1)
+
 #define PCIE_ARCACHE_TRC_REG		(PCIE_VENDOR_REGS_OFFSET + 0x50)
 #define PCIE_AWCACHE_TRC_REG		(PCIE_VENDOR_REGS_OFFSET + 0x54)
 #define PCIE_ARUSER_REG			(PCIE_VENDOR_REGS_OFFSET + 0x5C)
@@ -193,6 +197,11 @@ static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)
 	       PCIE_INT_C_ASSERT_MASK | PCIE_INT_D_ASSERT_MASK;
 	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK1_REG, reg);
 
+	/* Also enable link down interrupts */
+	reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG);
+	reg |= PCIE_INT2_PHY_RST_LINK_DOWN;
+	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG, reg);
+
 	if (!dw_pcie_link_up(pci)) {
 		/* Configuration done. Start LTSSM */
 		reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
@@ -230,6 +239,35 @@ static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg)
 	val = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_CAUSE1_REG);
 	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_CAUSE1_REG, val);
 
+	val = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_CAUSE2_REG);
+
+	if (PCIE_INT2_PHY_RST_LINK_DOWN & val) {
+		u32 ctrl_reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
+		/*
+		 * The link went down. Disable LTSSM immediately. This
+		 * unlocks the root complex config registers. Downstream
+		 * device accesses will return all-Fs
+		 */
+		ctrl_reg &= ~(PCIE_APP_LTSSM_EN);
+		dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, ctrl_reg);
+		/*
+		 * Mask link down interrupts. They can be re-enabled once
+		 * the link is retrained.
+		 */
+		ctrl_reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG);
+		ctrl_reg &= ~PCIE_INT2_PHY_RST_LINK_DOWN;
+		dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG, ctrl_reg);
+		/*
+		 * At this point a worker thread can be triggered to
+		 * initiate a link retrain. If link retrains were
+		 * possible, that is.
+		 */
+		dev_dbg(pci->dev, "%s: link went down\n", __func__);
+	}
+
+	/* Now clear the second interrupt cause. */
+	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_CAUSE2_REG, val);
+
 	return IRQ_HANDLED;
 }
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [”PATCH” v2 2/5] PCI: armada8k: Add link-down handle
  2021-04-14 13:20 [”PATCH” v2 0/5] Asynchronous linkdown recovery bpeled
  2021-04-14 13:20 ` [”PATCH” v2 1/5] PCI: armada8k: Disable LTSSM on link down interrupts bpeled
@ 2021-04-14 13:20 ` bpeled
  2021-04-17 10:51   ` Pali Rohár
  2021-04-14 13:20 ` [”PATCH” v2 3/5] dt-bindings: pci: add system controller and MAC reset bit to Armada 7K/8K controller bindings bpeled
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: bpeled @ 2021-04-14 13:20 UTC (permalink / raw)
  To: thomas.petazzoni, lorenzo.pieralisi, bhelgaas
  Cc: linux-kernel, linux-arm-kernel, devicetree, linux-pci,
	sebastian.hesselbarth, gregory.clement, andrew, robh+dt, mw, jaz,
	kostap, nadavh, stefanc, oferh, Ben Peled

From: Ben Peled <bpeled@marvell.com>

In PCIE ISR routine caused by RST_LINK_DOWN
we schedule work to handle the link-down procedure.
Link-down procedure will:
1. Remove PCIe bus
2. Reset the MAC
3. Reconfigure link back up
4. Rescan PCIe bus

Signed-off-by: Ben Peled <bpeled@marvell.com>
---
 drivers/pci/controller/dwc/pcie-armada8k.c | 69 ++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
index b2278b1..34b253c 100644
--- a/drivers/pci/controller/dwc/pcie-armada8k.c
+++ b/drivers/pci/controller/dwc/pcie-armada8k.c
@@ -22,6 +22,8 @@
 #include <linux/resource.h>
 #include <linux/of_pci.h>
 #include <linux/of_irq.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include "pcie-designware.h"
 
@@ -33,6 +35,9 @@ struct armada8k_pcie {
 	struct clk *clk_reg;
 	struct phy *phy[ARMADA8K_PCIE_MAX_LANES];
 	unsigned int phy_count;
+	struct regmap *sysctrl_base;
+	u32 mac_rest_bitmask;
+	struct work_struct recover_link_work;
 };
 
 #define PCIE_VENDOR_REGS_OFFSET		0x8000
@@ -73,6 +78,8 @@ struct armada8k_pcie {
 #define AX_USER_DOMAIN_MASK		0x3
 #define AX_USER_DOMAIN_SHIFT		4
 
+#define UNIT_SOFT_RESET_CONFIG_REG	0x268
+
 #define to_armada8k_pcie(x)	dev_get_drvdata((x)->dev)
 
 static void armada8k_pcie_disable_phys(struct armada8k_pcie *pcie)
@@ -225,6 +232,50 @@ static int armada8k_pcie_host_init(struct pcie_port *pp)
 	return 0;
 }
 
+static void armada8k_pcie_recover_link(struct work_struct *ws)
+{
+	struct armada8k_pcie *pcie = container_of(ws, struct armada8k_pcie, recover_link_work);
+	struct pcie_port *pp = &pcie->pci->pp;
+	struct pci_bus *bus = pp->bridge->bus;
+	struct pci_dev *root_port;
+	int ret;
+
+	root_port = pci_get_slot(bus, 0);
+	if (!root_port) {
+		dev_err(pcie->pci->dev, "failed to get root port\n");
+		return;
+	}
+	pci_lock_rescan_remove();
+	pci_stop_and_remove_bus_device(root_port);
+	/*
+	 * Sleep needed to make sure all pcie transactions and access
+	 * are flushed before resetting the mac
+	 */
+	msleep(100);
+
+	/* Reset mac */
+	regmap_update_bits_base(pcie->sysctrl_base, UNIT_SOFT_RESET_CONFIG_REG,
+				pcie->mac_rest_bitmask, 0, NULL, false, true);
+	udelay(1);
+	regmap_update_bits_base(pcie->sysctrl_base, UNIT_SOFT_RESET_CONFIG_REG,
+				pcie->mac_rest_bitmask, pcie->mac_rest_bitmask,
+				NULL, false, true);
+	udelay(1);
+	ret = armada8k_pcie_host_init(pp);
+	if (ret) {
+		dev_err(pcie->pci->dev, "failed to initialize host: %d\n", ret);
+		pci_unlock_rescan_remove();
+		pci_dev_put(root_port);
+		return;
+	}
+
+	bus = NULL;
+	while ((bus = pci_find_next_bus(bus)) != NULL)
+		pci_rescan_bus(bus);
+	pci_unlock_rescan_remove();
+	pci_dev_put(root_port);
+}
+
 static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg)
 {
 	struct armada8k_pcie *pcie = arg;
@@ -262,6 +313,9 @@ static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg)
 		 * initiate a link retrain. If link retrains were
 		 * possible, that is.
 		 */
+		if (pcie->sysctrl_base && pcie->mac_rest_bitmask)
+			schedule_work(&pcie->recover_link_work);
+
 		dev_dbg(pci->dev, "%s: link went down\n", __func__);
 	}
 
@@ -330,6 +384,8 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
 
 	pcie->pci = pci;
 
+	INIT_WORK(&pcie->recover_link_work, armada8k_pcie_recover_link);
+
 	pcie->clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(pcie->clk))
 		return PTR_ERR(pcie->clk);
@@ -357,6 +413,19 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
 		goto fail_clkreg;
 	}
 
+	pcie->sysctrl_base = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+						       "marvell,system-controller");
+	if (IS_ERR(pcie->sysctrl_base)) {
+		dev_warn(dev, "failed to find marvell,system-controller\n");
+		pcie->sysctrl_base = 0x0;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "marvell,mac-reset-bit-mask",
+				   &pcie->mac_rest_bitmask);
+	if (ret < 0) {
+		dev_warn(dev, "couldn't find mac reset bit mask: %d\n", ret);
+		pcie->mac_rest_bitmask = 0x0;
+	}
 	ret = armada8k_pcie_setup_phys(pcie);
 	if (ret)
 		goto fail_clkreg;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [”PATCH” v2 3/5] dt-bindings: pci: add system controller and MAC reset bit to Armada 7K/8K controller bindings
  2021-04-14 13:20 [”PATCH” v2 0/5] Asynchronous linkdown recovery bpeled
  2021-04-14 13:20 ` [”PATCH” v2 1/5] PCI: armada8k: Disable LTSSM on link down interrupts bpeled
  2021-04-14 13:20 ` [”PATCH” v2 2/5] PCI: armada8k: Add link-down handle bpeled
@ 2021-04-14 13:20 ` bpeled
  2021-04-15 21:20   ` Rob Herring
  2021-04-14 13:20 ` [”PATCH” v2 4/5] arm64: dts: marvell: add pcie mac reset to pcie bpeled
  2021-04-14 13:20 ` [”PATCH” v2 5/5] PCI: armada8k: add device reset to link-down handle bpeled
  4 siblings, 1 reply; 9+ messages in thread
From: bpeled @ 2021-04-14 13:20 UTC (permalink / raw)
  To: thomas.petazzoni, lorenzo.pieralisi, bhelgaas
  Cc: linux-kernel, linux-arm-kernel, devicetree, linux-pci,
	sebastian.hesselbarth, gregory.clement, andrew, robh+dt, mw, jaz,
	kostap, nadavh, stefanc, oferh, Ben Peled

From: Ben Peled <bpeled@marvell.com>

Adding optional system-controller and mac-reset-bit-mask
needed for linkdown procedure.

Signed-off-by: Ben Peled <bpeled@marvell.com>
---
 Documentation/devicetree/bindings/pci/pci-armada8k.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/pci-armada8k.txt b/Documentation/devicetree/bindings/pci/pci-armada8k.txt
index 7a813d0..2696e79 100644
--- a/Documentation/devicetree/bindings/pci/pci-armada8k.txt
+++ b/Documentation/devicetree/bindings/pci/pci-armada8k.txt
@@ -24,6 +24,10 @@ Optional properties:
 - phy-names: names of the PHYs corresponding to the number of lanes.
 	Must be "cp0-pcie0-x4-lane0-phy", "cp0-pcie0-x4-lane1-phy" for
 	2 PHYs.
+- marvell,system-controller: address of system controller needed
+	in order to reset MAC used by link-down handle
+- marvell,mac-reset-bit-mask: MAC reset bit of system controller
+	needed in order to reset MAC used by link-down handle
 
 Example:
 
@@ -45,4 +49,6 @@ Example:
 		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 		num-lanes = <1>;
 		clocks = <&cpm_syscon0 1 13>;
+		marvell,system-controller = <&CP11X_LABEL(syscon0)>;
+		marvell,mac-reset-bit-mask = <CP11X_PCIEx_MAC_RESET_BIT_MASK(1)>;
 	};
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [”PATCH” v2 4/5] arm64: dts: marvell: add pcie mac reset to pcie
  2021-04-14 13:20 [”PATCH” v2 0/5] Asynchronous linkdown recovery bpeled
                   ` (2 preceding siblings ...)
  2021-04-14 13:20 ` [”PATCH” v2 3/5] dt-bindings: pci: add system controller and MAC reset bit to Armada 7K/8K controller bindings bpeled
@ 2021-04-14 13:20 ` bpeled
  2021-04-14 13:20 ` [”PATCH” v2 5/5] PCI: armada8k: add device reset to link-down handle bpeled
  4 siblings, 0 replies; 9+ messages in thread
From: bpeled @ 2021-04-14 13:20 UTC (permalink / raw)
  To: thomas.petazzoni, lorenzo.pieralisi, bhelgaas
  Cc: linux-kernel, linux-arm-kernel, devicetree, linux-pci,
	sebastian.hesselbarth, gregory.clement, andrew, robh+dt, mw, jaz,
	kostap, nadavh, stefanc, oferh, Ben Peled

From: Ben Peled <bpeled@marvell.com>

Add system controller and reset bit to each pcie to enable pcie mac reset

Signed-off-by: Ben Peled <bpeled@marvell.com>
---
 arch/arm64/boot/dts/marvell/armada-cp11x.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
index 9dcf16b..eb60e73 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
@@ -11,6 +11,7 @@
 #include "armada-common.dtsi"
 
 #define CP11X_PCIEx_CONF_BASE(iface)	(CP11X_PCIEx_MEM_BASE(iface) + CP11X_PCIEx_MEM_SIZE(iface))
+#define CP11X_PCIEx_MAC_RESET_BIT_MASK(n)	(0x1 << 11 + ((n + 2) % 3))
 
 / {
 	/*
@@ -513,6 +514,8 @@
 		num-lanes = <1>;
 		clock-names = "core", "reg";
 		clocks = <&CP11X_LABEL(clk) 1 13>, <&CP11X_LABEL(clk) 1 14>;
+		marvell,system-controller = <&CP11X_LABEL(syscon0)>;
+		marvell,mac-reset-bit-mask = <CP11X_PCIEx_MAC_RESET_BIT_MASK(0)>;
 		status = "disabled";
 	};
 
@@ -538,6 +541,8 @@
 		num-lanes = <1>;
 		clock-names = "core", "reg";
 		clocks = <&CP11X_LABEL(clk) 1 11>, <&CP11X_LABEL(clk) 1 14>;
+		marvell,system-controller = <&CP11X_LABEL(syscon0)>;
+		marvell,mac-reset-bit-mask = <CP11X_PCIEx_MAC_RESET_BIT_MASK(1)>;
 		status = "disabled";
 	};
 
@@ -563,6 +568,8 @@
 		num-lanes = <1>;
 		clock-names = "core", "reg";
 		clocks = <&CP11X_LABEL(clk) 1 12>, <&CP11X_LABEL(clk) 1 14>;
+		marvell,system-controller = <&CP11X_LABEL(syscon0)>;
+		marvell,mac-reset-bit-mask = <CP11X_PCIEx_MAC_RESET_BIT_MASK(2)>;
 		status = "disabled";
 	};
 };
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [”PATCH” v2 5/5] PCI: armada8k: add device reset to link-down handle
  2021-04-14 13:20 [”PATCH” v2 0/5] Asynchronous linkdown recovery bpeled
                   ` (3 preceding siblings ...)
  2021-04-14 13:20 ` [”PATCH” v2 4/5] arm64: dts: marvell: add pcie mac reset to pcie bpeled
@ 2021-04-14 13:20 ` bpeled
  4 siblings, 0 replies; 9+ messages in thread
From: bpeled @ 2021-04-14 13:20 UTC (permalink / raw)
  To: thomas.petazzoni, lorenzo.pieralisi, bhelgaas
  Cc: linux-kernel, linux-arm-kernel, devicetree, linux-pci,
	sebastian.hesselbarth, gregory.clement, andrew, robh+dt, mw, jaz,
	kostap, nadavh, stefanc, oferh, Ben Peled

From: Ben Peled <bpeled@marvell.com>

Added pcie reset via gpio support as described in the
designware-pcie.txt DT binding document.
In cases link down cause still exist in device.
The device need to be reset to reestablish the link.
If reset-gpio pin provided in the device tree, then the linkdown
handle resets the device before reestablishing link.

Signed-off-by: Ben Peled <bpeled@marvell.com>
---
 drivers/pci/controller/dwc/pcie-armada8k.c | 24 ++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
index 34b253c..04bba97 100644
--- a/drivers/pci/controller/dwc/pcie-armada8k.c
+++ b/drivers/pci/controller/dwc/pcie-armada8k.c
@@ -24,6 +24,7 @@
 #include <linux/of_irq.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/of_gpio.h>
 
 #include "pcie-designware.h"
 
@@ -38,6 +39,8 @@ struct armada8k_pcie {
 	struct regmap *sysctrl_base;
 	u32 mac_rest_bitmask;
 	struct work_struct recover_link_work;
+	enum of_gpio_flags flags;
+	struct gpio_desc *reset_gpio;
 };
 
 #define PCIE_VENDOR_REGS_OFFSET		0x8000
@@ -247,9 +250,18 @@ static void armada8k_pcie_recover_link(struct work_struct *ws)
 	}
 	pci_lock_rescan_remove();
 	pci_stop_and_remove_bus_device(root_port);
+	/* Reset device if reset gpio is set */
+	if (pcie->reset_gpio) {
+		/* assert and then deassert the reset signal */
+		gpiod_set_value_cansleep(pcie->reset_gpio, 0);
+		msleep(100);
+		gpiod_set_value_cansleep(pcie->reset_gpio,
+					 (pcie->flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1);
+	}
 	/*
-	 * Sleep needed to make sure all pcie transactions and access
-	 * are flushed before resetting the mac
+	 * Sleep used for two reasons.
+	 * First make sure all pcie transactions and access are flushed before resetting the mac
+	 * and second to make sure pci device is ready in case we reset the device
 	 */
 	msleep(100);
 
@@ -369,6 +381,7 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
 	struct armada8k_pcie *pcie;
 	struct device *dev = &pdev->dev;
 	struct resource *base;
+	int reset_gpio;
 	int ret;
 
 	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
@@ -413,6 +426,13 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
 		goto fail_clkreg;
 	}
 
+	/* Config reset gpio for pcie if the reset connected to gpio */
+	reset_gpio = of_get_named_gpio_flags(pdev->dev.of_node,
+					     "reset-gpios", 0,
+					     &pcie->flags);
+	if (gpio_is_valid(reset_gpio))
+		pcie->reset_gpio = gpio_to_desc(reset_gpio);
+
 	pcie->sysctrl_base = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 						       "marvell,system-controller");
 	if (IS_ERR(pcie->sysctrl_base)) {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [”PATCH” v2 3/5] dt-bindings: pci: add system controller and MAC reset bit to Armada 7K/8K controller bindings
  2021-04-14 13:20 ` [”PATCH” v2 3/5] dt-bindings: pci: add system controller and MAC reset bit to Armada 7K/8K controller bindings bpeled
@ 2021-04-15 21:20   ` Rob Herring
  0 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2021-04-15 21:20 UTC (permalink / raw)
  To: bpeled
  Cc: thomas.petazzoni, lorenzo.pieralisi, bhelgaas, linux-kernel,
	linux-arm-kernel, devicetree, linux-pci, sebastian.hesselbarth,
	gregory.clement, andrew, mw, jaz, kostap, nadavh, stefanc, oferh

On Wed, Apr 14, 2021 at 04:20:52PM +0300, bpeled@marvell.com wrote:
> From: Ben Peled <bpeled@marvell.com>
> 
> Adding optional system-controller and mac-reset-bit-mask
> needed for linkdown procedure.

Same comment as v1.

BTW, it's PATCH not "PATCH". Don't do anything and git will do the right 
thing here.

> 
> Signed-off-by: Ben Peled <bpeled@marvell.com>
> ---
>  Documentation/devicetree/bindings/pci/pci-armada8k.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/pci-armada8k.txt b/Documentation/devicetree/bindings/pci/pci-armada8k.txt
> index 7a813d0..2696e79 100644
> --- a/Documentation/devicetree/bindings/pci/pci-armada8k.txt
> +++ b/Documentation/devicetree/bindings/pci/pci-armada8k.txt
> @@ -24,6 +24,10 @@ Optional properties:
>  - phy-names: names of the PHYs corresponding to the number of lanes.
>  	Must be "cp0-pcie0-x4-lane0-phy", "cp0-pcie0-x4-lane1-phy" for
>  	2 PHYs.
> +- marvell,system-controller: address of system controller needed
> +	in order to reset MAC used by link-down handle
> +- marvell,mac-reset-bit-mask: MAC reset bit of system controller
> +	needed in order to reset MAC used by link-down handle
>  
>  Example:
>  
> @@ -45,4 +49,6 @@ Example:
>  		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>  		num-lanes = <1>;
>  		clocks = <&cpm_syscon0 1 13>;
> +		marvell,system-controller = <&CP11X_LABEL(syscon0)>;
> +		marvell,mac-reset-bit-mask = <CP11X_PCIEx_MAC_RESET_BIT_MASK(1)>;
>  	};
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [”PATCH” v2 2/5] PCI: armada8k: Add link-down handle
  2021-04-14 13:20 ` [”PATCH” v2 2/5] PCI: armada8k: Add link-down handle bpeled
@ 2021-04-17 10:51   ` Pali Rohár
  0 siblings, 0 replies; 9+ messages in thread
From: Pali Rohár @ 2021-04-17 10:51 UTC (permalink / raw)
  To: bpeled
  Cc: thomas.petazzoni, lorenzo.pieralisi, bhelgaas, linux-kernel,
	linux-arm-kernel, devicetree, linux-pci, sebastian.hesselbarth,
	gregory.clement, andrew, robh+dt, mw, jaz, kostap, nadavh,
	stefanc, oferh

On Wednesday 14 April 2021 16:20:51 bpeled@marvell.com wrote:
> From: Ben Peled <bpeled@marvell.com>
> 
> In PCIE ISR routine caused by RST_LINK_DOWN
> we schedule work to handle the link-down procedure.
> Link-down procedure will:
> 1. Remove PCIe bus
> 2. Reset the MAC
> 3. Reconfigure link back up
> 4. Rescan PCIe bus

Hello! This looks like a part of PCIe Hot Plug procedure, which is
already handled by kernel pci hotplug code, it can detect link down
interrupt and remove PCI device from the bus. I'm not sure if it would
not be better to use existing "infrastructure" for hotplug rather then
implementing new in controller driver. But I do not know what is
"correct" way, so I hope that other people (maybe Bjorn?) would say
something about this topic.

> Signed-off-by: Ben Peled <bpeled@marvell.com>
> ---
>  drivers/pci/controller/dwc/pcie-armada8k.c | 69 ++++++++++++++++++++
>  1 file changed, 69 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
> index b2278b1..34b253c 100644
> --- a/drivers/pci/controller/dwc/pcie-armada8k.c
> +++ b/drivers/pci/controller/dwc/pcie-armada8k.c
> @@ -22,6 +22,8 @@
>  #include <linux/resource.h>
>  #include <linux/of_pci.h>
>  #include <linux/of_irq.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
>  
>  #include "pcie-designware.h"
>  
> @@ -33,6 +35,9 @@ struct armada8k_pcie {
>  	struct clk *clk_reg;
>  	struct phy *phy[ARMADA8K_PCIE_MAX_LANES];
>  	unsigned int phy_count;
> +	struct regmap *sysctrl_base;
> +	u32 mac_rest_bitmask;
> +	struct work_struct recover_link_work;
>  };
>  
>  #define PCIE_VENDOR_REGS_OFFSET		0x8000
> @@ -73,6 +78,8 @@ struct armada8k_pcie {
>  #define AX_USER_DOMAIN_MASK		0x3
>  #define AX_USER_DOMAIN_SHIFT		4
>  
> +#define UNIT_SOFT_RESET_CONFIG_REG	0x268
> +
>  #define to_armada8k_pcie(x)	dev_get_drvdata((x)->dev)
>  
>  static void armada8k_pcie_disable_phys(struct armada8k_pcie *pcie)
> @@ -225,6 +232,50 @@ static int armada8k_pcie_host_init(struct pcie_port *pp)
>  	return 0;
>  }
>  
> +static void armada8k_pcie_recover_link(struct work_struct *ws)
> +{
> +	struct armada8k_pcie *pcie = container_of(ws, struct armada8k_pcie, recover_link_work);
> +	struct pcie_port *pp = &pcie->pci->pp;
> +	struct pci_bus *bus = pp->bridge->bus;
> +	struct pci_dev *root_port;
> +	int ret;
> +
> +	root_port = pci_get_slot(bus, 0);
> +	if (!root_port) {
> +		dev_err(pcie->pci->dev, "failed to get root port\n");
> +		return;
> +	}
> +	pci_lock_rescan_remove();
> +	pci_stop_and_remove_bus_device(root_port);
> +	/*
> +	 * Sleep needed to make sure all pcie transactions and access
> +	 * are flushed before resetting the mac
> +	 */
> +	msleep(100);
> +
> +	/* Reset mac */
> +	regmap_update_bits_base(pcie->sysctrl_base, UNIT_SOFT_RESET_CONFIG_REG,
> +				pcie->mac_rest_bitmask, 0, NULL, false, true);
> +	udelay(1);
> +	regmap_update_bits_base(pcie->sysctrl_base, UNIT_SOFT_RESET_CONFIG_REG,
> +				pcie->mac_rest_bitmask, pcie->mac_rest_bitmask,
> +				NULL, false, true);
> +	udelay(1);
> +	ret = armada8k_pcie_host_init(pp);
> +	if (ret) {
> +		dev_err(pcie->pci->dev, "failed to initialize host: %d\n", ret);
> +		pci_unlock_rescan_remove();
> +		pci_dev_put(root_port);
> +		return;
> +	}
> +
> +	bus = NULL;
> +	while ((bus = pci_find_next_bus(bus)) != NULL)
> +		pci_rescan_bus(bus);
> +	pci_unlock_rescan_remove();
> +	pci_dev_put(root_port);
> +}
> +
>  static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg)
>  {
>  	struct armada8k_pcie *pcie = arg;
> @@ -262,6 +313,9 @@ static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg)
>  		 * initiate a link retrain. If link retrains were
>  		 * possible, that is.
>  		 */
> +		if (pcie->sysctrl_base && pcie->mac_rest_bitmask)
> +			schedule_work(&pcie->recover_link_work);
> +
>  		dev_dbg(pci->dev, "%s: link went down\n", __func__);
>  	}
>  
> @@ -330,6 +384,8 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
>  
>  	pcie->pci = pci;
>  
> +	INIT_WORK(&pcie->recover_link_work, armada8k_pcie_recover_link);
> +
>  	pcie->clk = devm_clk_get(dev, NULL);
>  	if (IS_ERR(pcie->clk))
>  		return PTR_ERR(pcie->clk);
> @@ -357,6 +413,19 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
>  		goto fail_clkreg;
>  	}
>  
> +	pcie->sysctrl_base = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> +						       "marvell,system-controller");
> +	if (IS_ERR(pcie->sysctrl_base)) {
> +		dev_warn(dev, "failed to find marvell,system-controller\n");
> +		pcie->sysctrl_base = 0x0;
> +	}
> +
> +	ret = of_property_read_u32(pdev->dev.of_node, "marvell,mac-reset-bit-mask",
> +				   &pcie->mac_rest_bitmask);
> +	if (ret < 0) {
> +		dev_warn(dev, "couldn't find mac reset bit mask: %d\n", ret);
> +		pcie->mac_rest_bitmask = 0x0;
> +	}
>  	ret = armada8k_pcie_setup_phys(pcie);
>  	if (ret)
>  		goto fail_clkreg;
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [”PATCH” v2 1/5] PCI: armada8k: Disable LTSSM on link down interrupts
  2021-04-14 13:20 ` [”PATCH” v2 1/5] PCI: armada8k: Disable LTSSM on link down interrupts bpeled
@ 2021-12-09 11:28   ` Pali Rohár
  0 siblings, 0 replies; 9+ messages in thread
From: Pali Rohár @ 2021-12-09 11:28 UTC (permalink / raw)
  To: bpeled, kostap, nadavh, stefanc, oferh, Marc St-Amand, mw, jaz
  Cc: thomas.petazzoni, lorenzo.pieralisi, bhelgaas, linux-kernel,
	linux-arm-kernel, devicetree, linux-pci, sebastian.hesselbarth,
	gregory.clement, andrew, robh+dt

On Wednesday 14 April 2021 16:20:50 bpeled@marvell.com wrote:
> From: Ben Peled <bpeled@marvell.com>
> 
> When a PCI link down condition is detected, the link training state
> machine must be disabled immediately.
> 
> Signed-off-by: Marc St-Amand <mstamand@ciena.com>
> Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
> Signed-off-by: Ben Peled <bpeled@marvell.com>
> ---
>  drivers/pci/controller/dwc/pcie-armada8k.c | 38 ++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
> index 13901f3..b2278b1 100644
> --- a/drivers/pci/controller/dwc/pcie-armada8k.c
> +++ b/drivers/pci/controller/dwc/pcie-armada8k.c
> @@ -54,6 +54,10 @@ struct armada8k_pcie {
>  #define PCIE_INT_C_ASSERT_MASK		BIT(11)
>  #define PCIE_INT_D_ASSERT_MASK		BIT(12)
>  
> +#define PCIE_GLOBAL_INT_CAUSE2_REG	(PCIE_VENDOR_REGS_OFFSET + 0x24)
> +#define PCIE_GLOBAL_INT_MASK2_REG	(PCIE_VENDOR_REGS_OFFSET + 0x28)
> +#define PCIE_INT2_PHY_RST_LINK_DOWN	BIT(1)
> +
>  #define PCIE_ARCACHE_TRC_REG		(PCIE_VENDOR_REGS_OFFSET + 0x50)
>  #define PCIE_AWCACHE_TRC_REG		(PCIE_VENDOR_REGS_OFFSET + 0x54)
>  #define PCIE_ARUSER_REG			(PCIE_VENDOR_REGS_OFFSET + 0x5C)
> @@ -193,6 +197,11 @@ static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)
>  	       PCIE_INT_C_ASSERT_MASK | PCIE_INT_D_ASSERT_MASK;
>  	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK1_REG, reg);
>  
> +	/* Also enable link down interrupts */
> +	reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG);
> +	reg |= PCIE_INT2_PHY_RST_LINK_DOWN;
> +	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG, reg);
> +
>  	if (!dw_pcie_link_up(pci)) {
>  		/* Configuration done. Start LTSSM */
>  		reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
> @@ -230,6 +239,35 @@ static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg)
>  	val = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_CAUSE1_REG);
>  	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_CAUSE1_REG, val);
>  
> +	val = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_CAUSE2_REG);
> +
> +	if (PCIE_INT2_PHY_RST_LINK_DOWN & val) {
> +		u32 ctrl_reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
> +		/*
> +		 * The link went down. Disable LTSSM immediately. This
> +		 * unlocks the root complex config registers. Downstream
> +		 * device accesses will return all-Fs
> +		 */

Hello! This looks like some issue with PCIe HW. Does it mean that if
LTSSM is not disabled then Root Complex stuck or crash during processing
config requests from CPU? Or what else happens?

Could you provide more details what is the exact issue described in this
comment? And is there any Marvell errata about this particular "disable
LTSSM immediately" issue?

> +		ctrl_reg &= ~(PCIE_APP_LTSSM_EN);
> +		dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, ctrl_reg);
> +		/*
> +		 * Mask link down interrupts. They can be re-enabled once
> +		 * the link is retrained.
> +		 */
> +		ctrl_reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG);
> +		ctrl_reg &= ~PCIE_INT2_PHY_RST_LINK_DOWN;
> +		dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK2_REG, ctrl_reg);
> +		/*
> +		 * At this point a worker thread can be triggered to
> +		 * initiate a link retrain. If link retrains were
> +		 * possible, that is.
> +		 */
> +		dev_dbg(pci->dev, "%s: link went down\n", __func__);
> +	}
> +
> +	/* Now clear the second interrupt cause. */
> +	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_CAUSE2_REG, val);
> +
>  	return IRQ_HANDLED;
>  }
>  
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-12-09 11:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-14 13:20 [”PATCH” v2 0/5] Asynchronous linkdown recovery bpeled
2021-04-14 13:20 ` [”PATCH” v2 1/5] PCI: armada8k: Disable LTSSM on link down interrupts bpeled
2021-12-09 11:28   ` Pali Rohár
2021-04-14 13:20 ` [”PATCH” v2 2/5] PCI: armada8k: Add link-down handle bpeled
2021-04-17 10:51   ` Pali Rohár
2021-04-14 13:20 ` [”PATCH” v2 3/5] dt-bindings: pci: add system controller and MAC reset bit to Armada 7K/8K controller bindings bpeled
2021-04-15 21:20   ` Rob Herring
2021-04-14 13:20 ` [”PATCH” v2 4/5] arm64: dts: marvell: add pcie mac reset to pcie bpeled
2021-04-14 13:20 ` [”PATCH” v2 5/5] PCI: armada8k: add device reset to link-down handle bpeled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).