All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4.4 0/7] PCI: altera: survive warm reboot
@ 2019-01-07 10:00 claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 1/7] PCI: altera: Fix altera_pcie_link_is_up() claudius.heine.ext
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Claudius Heine <ch@denx.de>

Hi,

after a warm reboot, the altera pcie host interface is not correctly
initialized in v4.4.

These patches from v4.9 solved that issue.

Claudius

Bjorn Helgaas (1):
  PCI: altera: Reorder read/write functions

Ley Foon Tan (6):
  PCI: altera: Fix altera_pcie_link_is_up()
  PCI: altera: Check link status before retrain link
  PCI: altera: Poll for link up status after retraining the link
  PCI: altera: Poll for link training status after retraining the link
  PCI: altera: Rework config accessors for use without a struct pci_bus
  PCI: altera: Move retrain from fixup to altera_pcie_host_init()

 drivers/pci/host/pcie-altera.c | 201 ++++++++++++++++++++++++---------
 1 file changed, 147 insertions(+), 54 deletions(-)

-- 
2.19.2


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

* [PATCH v4.4 1/7] PCI: altera: Fix altera_pcie_link_is_up()
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
@ 2019-01-07 10:00 ` claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 2/7] PCI: altera: Reorder read/write functions claudius.heine.ext
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Ley Foon Tan <lftan@altera.com>

commit eff31f4002c4e25b9b8c39d0a3a551c6c64c77e8 upstream

Originally altera_pcie_link_is_up() decided the link was up if any of the
low four bits of the LTSSM register were set.  But the link is only up if
the LTSSM state is L0, so check for that exact value.

[bhelgaas: changelog]
Signed-off-by: Ley Foon Tan <lftan@altera.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Claudius Heine <ch@denx.de>
---
 drivers/pci/host/pcie-altera.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index 99da549d5d06..dbac6fb3f0bd 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -40,6 +40,7 @@
 #define P2A_INT_ENABLE			0x3070
 #define P2A_INT_ENA_ALL			0xf
 #define RP_LTSSM			0x3c64
+#define RP_LTSSM_MASK			0x1f
 #define LTSSM_L0			0xf
 
 /* TLP configuration type 0 and 1 */
@@ -140,7 +141,7 @@ static void tlp_write_tx(struct altera_pcie *pcie,
 
 static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
 {
-	return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0);
+	return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
 }
 
 static bool altera_pcie_valid_config(struct altera_pcie *pcie,
-- 
2.19.2


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

* [PATCH v4.4 2/7] PCI: altera: Reorder read/write functions
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 1/7] PCI: altera: Fix altera_pcie_link_is_up() claudius.heine.ext
@ 2019-01-07 10:00 ` claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 3/7] PCI: altera: Check link status before retrain link claudius.heine.ext
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Bjorn Helgaas <bhelgaas@google.com>

commit f8be11ae3d2c9a1338da37ff91ff4c65922d21be upstream

Move cra_writel(), cra_readl(), and altera_pcie_link_is_up() so a future
patch can use them in altera_pcie_retrain().  No functional change
intended.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Claudius Heine <ch@denx.de>
---
 drivers/pci/host/pcie-altera.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index dbac6fb3f0bd..a1e782263dec 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -81,6 +81,22 @@ struct tlp_rp_regpair_t {
 	u32 reg1;
 };
 
+static inline void cra_writel(struct altera_pcie *pcie, const u32 value,
+			      const u32 reg)
+{
+	writel_relaxed(value, pcie->cra_base + reg);
+}
+
+static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg)
+{
+	return readl_relaxed(pcie->cra_base + reg);
+}
+
+static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
+{
+	return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
+}
+
 static void altera_pcie_retrain(struct pci_dev *dev)
 {
 	u16 linkcap, linkstat;
@@ -120,17 +136,6 @@ static bool altera_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int  devfn,
 	return false;
 }
 
-static inline void cra_writel(struct altera_pcie *pcie, const u32 value,
-			      const u32 reg)
-{
-	writel_relaxed(value, pcie->cra_base + reg);
-}
-
-static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg)
-{
-	return readl_relaxed(pcie->cra_base + reg);
-}
-
 static void tlp_write_tx(struct altera_pcie *pcie,
 			 struct tlp_rp_regpair_t *tlp_rp_regdata)
 {
@@ -139,11 +144,6 @@ static void tlp_write_tx(struct altera_pcie *pcie,
 	cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
 }
 
-static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
-{
-	return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
-}
-
 static bool altera_pcie_valid_config(struct altera_pcie *pcie,
 				     struct pci_bus *bus, int dev)
 {
-- 
2.19.2


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

* [PATCH v4.4 3/7] PCI: altera: Check link status before retrain link
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 1/7] PCI: altera: Fix altera_pcie_link_is_up() claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 2/7] PCI: altera: Reorder read/write functions claudius.heine.ext
@ 2019-01-07 10:00 ` claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 4/7] PCI: altera: Poll for link up status after retraining the link claudius.heine.ext
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Ley Foon Tan <lftan@altera.com>

commit c622032ebc538cb3869c312ae3ad235a99da84b6 upstream

Check the link status before retraining.  If the link is not up, don't
bother trying to retrain it.

[bhelgaas: split code move to separate patch, changelog]
Signed-off-by: Ley Foon Tan <lftan@altera.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Claudius Heine <ch@denx.de>
---
 drivers/pci/host/pcie-altera.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index a1e782263dec..b61025ee07de 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -100,6 +100,10 @@ static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
 static void altera_pcie_retrain(struct pci_dev *dev)
 {
 	u16 linkcap, linkstat;
+	struct altera_pcie *pcie = dev->bus->sysdata;
+
+	if (!altera_pcie_link_is_up(pcie))
+		return;
 
 	/*
 	 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
-- 
2.19.2


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

* [PATCH v4.4 4/7] PCI: altera: Poll for link up status after retraining the link
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
                   ` (2 preceding siblings ...)
  2019-01-07 10:00 ` [PATCH v4.4 3/7] PCI: altera: Check link status before retrain link claudius.heine.ext
@ 2019-01-07 10:00 ` claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 5/7] PCI: altera: Poll for link training " claudius.heine.ext
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Ley Foon Tan <lftan@altera.com>

commit 3a928e98a833e1a470a60d2fedf3c55502185fb7 upstream

Some PCIe devices take a long time to reach link up state after retrain.
Poll for link up status after retraining the link.  This is to make sure
the link is up before we access configuration space.

[bhelgaas: changelog]
Signed-off-by: Ley Foon Tan <lftan@altera.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Claudius Heine <ch@denx.de>
---
 drivers/pci/host/pcie-altera.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index b61025ee07de..e4154b2a23ce 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -61,6 +61,8 @@
 #define TLP_LOOP			500
 #define RP_DEVFN			0
 
+#define LINK_UP_TIMEOUT			5000
+
 #define INTX_NUM			4
 
 #define DWORD_MASK			3
@@ -101,6 +103,7 @@ static void altera_pcie_retrain(struct pci_dev *dev)
 {
 	u16 linkcap, linkstat;
 	struct altera_pcie *pcie = dev->bus->sysdata;
+	int timeout =  0;
 
 	if (!altera_pcie_link_is_up(pcie))
 		return;
@@ -115,9 +118,16 @@ static void altera_pcie_retrain(struct pci_dev *dev)
 		return;
 
 	pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
-	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB)
+	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
 		pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
 					 PCI_EXP_LNKCTL_RL);
+		while (!altera_pcie_link_is_up(pcie)) {
+			timeout++;
+			if (timeout > LINK_UP_TIMEOUT)
+				break;
+			udelay(5);
+		}
+	}
 }
 DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain);
 
-- 
2.19.2


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

* [PATCH v4.4 5/7] PCI: altera: Poll for link training status after retraining the link
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
                   ` (3 preceding siblings ...)
  2019-01-07 10:00 ` [PATCH v4.4 4/7] PCI: altera: Poll for link up status after retraining the link claudius.heine.ext
@ 2019-01-07 10:00 ` claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 6/7] PCI: altera: Rework config accessors for use without a struct pci_bus claudius.heine.ext
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Ley Foon Tan <lftan@altera.com>

commit 411dc32d8810e0a204c799ce5c97cb56990de1cb upstream

Poll for link training status is cleared before poll for link up status.
This can help to get the reliable link up status, especially when PCIe is
in Gen 3 speed.

Signed-off-by: Ley Foon Tan <lftan@altera.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Claudius Heine <ch@denx.de>
---
 drivers/pci/host/pcie-altera.c | 45 ++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index e4154b2a23ce..e0be9ac5701a 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -61,7 +61,8 @@
 #define TLP_LOOP			500
 #define RP_DEVFN			0
 
-#define LINK_UP_TIMEOUT			5000
+#define LINK_UP_TIMEOUT			HZ
+#define LINK_RETRAIN_TIMEOUT		HZ
 
 #define INTX_NUM			4
 
@@ -99,11 +100,44 @@ static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
 	return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
 }
 
+static void altera_wait_link_retrain(struct pci_dev *dev)
+{
+	u16 reg16;
+	unsigned long start_jiffies;
+	struct altera_pcie *pcie = dev->bus->sysdata;
+
+	/* Wait for link training end. */
+	start_jiffies = jiffies;
+	for (;;) {
+		pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &reg16);
+		if (!(reg16 & PCI_EXP_LNKSTA_LT))
+			break;
+
+		if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) {
+			dev_err(&pcie->pdev->dev, "link retrain timeout\n");
+			break;
+		}
+		udelay(100);
+	}
+
+	/* Wait for link is up */
+	start_jiffies = jiffies;
+	for (;;) {
+		if (altera_pcie_link_is_up(pcie))
+			break;
+
+		if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
+			dev_err(&pcie->pdev->dev, "link up timeout\n");
+			break;
+		}
+		udelay(100);
+	}
+}
+
 static void altera_pcie_retrain(struct pci_dev *dev)
 {
 	u16 linkcap, linkstat;
 	struct altera_pcie *pcie = dev->bus->sysdata;
-	int timeout =  0;
 
 	if (!altera_pcie_link_is_up(pcie))
 		return;
@@ -121,12 +155,7 @@ static void altera_pcie_retrain(struct pci_dev *dev)
 	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
 		pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
 					 PCI_EXP_LNKCTL_RL);
-		while (!altera_pcie_link_is_up(pcie)) {
-			timeout++;
-			if (timeout > LINK_UP_TIMEOUT)
-				break;
-			udelay(5);
-		}
+		altera_wait_link_retrain(dev);
 	}
 }
 DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain);
-- 
2.19.2


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

* [PATCH v4.4 6/7] PCI: altera: Rework config accessors for use without a struct pci_bus
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
                   ` (4 preceding siblings ...)
  2019-01-07 10:00 ` [PATCH v4.4 5/7] PCI: altera: Poll for link training " claudius.heine.ext
@ 2019-01-07 10:00 ` claudius.heine.ext
  2019-01-07 10:00 ` [PATCH v4.4 7/7] PCI: altera: Move retrain from fixup to altera_pcie_host_init() claudius.heine.ext
  2019-01-10 19:15 ` [PATCH v4.4 0/7] PCI: altera: survive warm reboot Greg KH
  7 siblings, 0 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Ley Foon Tan <lftan@altera.com>

commit 31fc0ad47e2e0b8417616aa0f1ddcc67edf1e109 upstream

Rework configs accessors so a future patch can use them in _probe() with
struct altera_pcie instead of struct pci_bus.

Signed-off-by: Ley Foon Tan <lftan@altera.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Claudius Heine <ch@denx.de>
---
 drivers/pci/host/pcie-altera.c | 64 ++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 23 deletions(-)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index e0be9ac5701a..a95c9c4e03c7 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -330,22 +330,14 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
-				int where, int size, u32 *value)
+static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno,
+				 unsigned int devfn, int where, int size,
+				 u32 *value)
 {
-	struct altera_pcie *pcie = bus->sysdata;
 	int ret;
 	u32 data;
 	u8 byte_en;
 
-	if (altera_pcie_hide_rc_bar(bus, devfn, where))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
-		*value = 0xffffffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-
 	switch (size) {
 	case 1:
 		byte_en = 1 << (where & 3);
@@ -358,7 +350,7 @@ static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
 		break;
 	}
 
-	ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
+	ret = tlp_cfg_dword_read(pcie, busno, devfn,
 				 (where & ~DWORD_MASK), byte_en, &data);
 	if (ret != PCIBIOS_SUCCESSFUL)
 		return ret;
@@ -378,20 +370,14 @@ static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
-				 int where, int size, u32 value)
+static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno,
+				  unsigned int devfn, int where, int size,
+				  u32 value)
 {
-	struct altera_pcie *pcie = bus->sysdata;
 	u32 data32;
 	u32 shift = 8 * (where & 3);
 	u8 byte_en;
 
-	if (altera_pcie_hide_rc_bar(bus, devfn, where))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
 	switch (size) {
 	case 1:
 		data32 = (value & 0xff) << shift;
@@ -407,8 +393,40 @@ static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
 		break;
 	}
 
-	return tlp_cfg_dword_write(pcie, bus->number, devfn,
-		(where & ~DWORD_MASK), byte_en, data32);
+	return tlp_cfg_dword_write(pcie, busno, devfn, (where & ~DWORD_MASK),
+				   byte_en, data32);
+}
+
+static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
+				int where, int size, u32 *value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+
+	if (altera_pcie_hide_rc_bar(bus, devfn, where))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
+		*value = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return _altera_pcie_cfg_read(pcie, bus->number, devfn, where, size,
+				     value);
+}
+
+static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+
+	if (altera_pcie_hide_rc_bar(bus, devfn, where))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return _altera_pcie_cfg_write(pcie, bus->number, devfn, where, size,
+				     value);
 }
 
 static struct pci_ops altera_pcie_ops = {
-- 
2.19.2


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

* [PATCH v4.4 7/7] PCI: altera: Move retrain from fixup to altera_pcie_host_init()
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
                   ` (5 preceding siblings ...)
  2019-01-07 10:00 ` [PATCH v4.4 6/7] PCI: altera: Rework config accessors for use without a struct pci_bus claudius.heine.ext
@ 2019-01-07 10:00 ` claudius.heine.ext
  2019-01-10 19:15 ` [PATCH v4.4 0/7] PCI: altera: survive warm reboot Greg KH
  7 siblings, 0 replies; 12+ messages in thread
From: claudius.heine.ext @ 2019-01-07 10:00 UTC (permalink / raw)
  To: stable; +Cc: Bjorn Helgaas, Ley Foon Tan, Claudius Heine

From: Ley Foon Tan <lftan@altera.com>

commit ce4f1c7ad490aa7129bde5632d6e53943f8a866c upstream

Previously we used a PCI early fixup to initiate a link retrain on Altera
devices.  But Altera PCIe IP can be configured as either a Root Port or an
Endpoint, and they might have same vendor ID, so the fixup would be run for
both.

We only want to initiate a link retrain for Altera Root Port devices, not
for Endpoints, so move the link retrain functionality from the fixup to
altera_pcie_host_init().

[bhelgaas: changelog]
Signed-off-by: Ley Foon Tan <lftan@altera.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Claudius Heine <ch@denx.de>
---
 drivers/pci/host/pcie-altera.c | 151 ++++++++++++++++++++-------------
 1 file changed, 91 insertions(+), 60 deletions(-)

diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index a95c9c4e03c7..0118287a8a10 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -43,6 +43,7 @@
 #define RP_LTSSM_MASK			0x1f
 #define LTSSM_L0			0xf
 
+#define PCIE_CAP_OFFSET			0x80
 /* TLP configuration type 0 and 1 */
 #define TLP_FMTTYPE_CFGRD0		0x04	/* Configuration Read Type 0 */
 #define TLP_FMTTYPE_CFGWR0		0x44	/* Configuration Write Type 0 */
@@ -100,66 +101,6 @@ static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
 	return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
 }
 
-static void altera_wait_link_retrain(struct pci_dev *dev)
-{
-	u16 reg16;
-	unsigned long start_jiffies;
-	struct altera_pcie *pcie = dev->bus->sysdata;
-
-	/* Wait for link training end. */
-	start_jiffies = jiffies;
-	for (;;) {
-		pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &reg16);
-		if (!(reg16 & PCI_EXP_LNKSTA_LT))
-			break;
-
-		if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) {
-			dev_err(&pcie->pdev->dev, "link retrain timeout\n");
-			break;
-		}
-		udelay(100);
-	}
-
-	/* Wait for link is up */
-	start_jiffies = jiffies;
-	for (;;) {
-		if (altera_pcie_link_is_up(pcie))
-			break;
-
-		if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
-			dev_err(&pcie->pdev->dev, "link up timeout\n");
-			break;
-		}
-		udelay(100);
-	}
-}
-
-static void altera_pcie_retrain(struct pci_dev *dev)
-{
-	u16 linkcap, linkstat;
-	struct altera_pcie *pcie = dev->bus->sysdata;
-
-	if (!altera_pcie_link_is_up(pcie))
-		return;
-
-	/*
-	 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
-	 * current speed is 2.5 GB/s.
-	 */
-	pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
-
-	if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
-		return;
-
-	pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
-	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
-		pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
-					 PCI_EXP_LNKCTL_RL);
-		altera_wait_link_retrain(dev);
-	}
-}
-DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain);
-
 /*
  * Altera PCIe port uses BAR0 of RC's configuration space as the translation
  * from PCI bus to native BUS.  Entire DDR region is mapped into PCIe space
@@ -434,6 +375,90 @@ static struct pci_ops altera_pcie_ops = {
 	.write = altera_pcie_cfg_write,
 };
 
+static int altera_read_cap_word(struct altera_pcie *pcie, u8 busno,
+				unsigned int devfn, int offset, u16 *value)
+{
+	u32 data;
+	int ret;
+
+	ret = _altera_pcie_cfg_read(pcie, busno, devfn,
+				    PCIE_CAP_OFFSET + offset, sizeof(*value),
+				    &data);
+	*value = data;
+	return ret;
+}
+
+static int altera_write_cap_word(struct altera_pcie *pcie, u8 busno,
+				 unsigned int devfn, int offset, u16 value)
+{
+	return _altera_pcie_cfg_write(pcie, busno, devfn,
+				      PCIE_CAP_OFFSET + offset, sizeof(value),
+				      value);
+}
+
+static void altera_wait_link_retrain(struct altera_pcie *pcie)
+{
+	u16 reg16;
+	unsigned long start_jiffies;
+
+	/* Wait for link training end. */
+	start_jiffies = jiffies;
+	for (;;) {
+		altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
+				     PCI_EXP_LNKSTA, &reg16);
+		if (!(reg16 & PCI_EXP_LNKSTA_LT))
+			break;
+
+		if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) {
+			dev_err(&pcie->pdev->dev, "link retrain timeout\n");
+			break;
+		}
+		udelay(100);
+	}
+
+	/* Wait for link is up */
+	start_jiffies = jiffies;
+	for (;;) {
+		if (altera_pcie_link_is_up(pcie))
+			break;
+
+		if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
+			dev_err(&pcie->pdev->dev, "link up timeout\n");
+			break;
+		}
+		udelay(100);
+	}
+}
+
+static void altera_pcie_retrain(struct altera_pcie *pcie)
+{
+	u16 linkcap, linkstat, linkctl;
+
+	if (!altera_pcie_link_is_up(pcie))
+		return;
+
+	/*
+	 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
+	 * current speed is 2.5 GB/s.
+	 */
+	altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKCAP,
+			     &linkcap);
+	if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
+		return;
+
+	altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKSTA,
+			     &linkstat);
+	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
+		altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
+				     PCI_EXP_LNKCTL, &linkctl);
+		linkctl |= PCI_EXP_LNKCTL_RL;
+		altera_write_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
+				      PCI_EXP_LNKCTL, linkctl);
+
+		altera_wait_link_retrain(pcie);
+	}
+}
+
 static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
 				irq_hw_number_t hwirq)
 {
@@ -568,6 +593,11 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
 	return 0;
 }
 
+static void altera_pcie_host_init(struct altera_pcie *pcie)
+{
+	altera_pcie_retrain(pcie);
+}
+
 static int altera_pcie_probe(struct platform_device *pdev)
 {
 	struct altera_pcie *pcie;
@@ -605,6 +635,7 @@ static int altera_pcie_probe(struct platform_device *pdev)
 	cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
 	/* enable all interrupts */
 	cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
+	altera_pcie_host_init(pcie);
 
 	bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
 				pcie, &pcie->resources);
-- 
2.19.2


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

* Re: [PATCH v4.4 0/7] PCI: altera: survive warm reboot
  2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
                   ` (6 preceding siblings ...)
  2019-01-07 10:00 ` [PATCH v4.4 7/7] PCI: altera: Move retrain from fixup to altera_pcie_host_init() claudius.heine.ext
@ 2019-01-10 19:15 ` Greg KH
  2019-01-14  8:24   ` Claudius Heine
  7 siblings, 1 reply; 12+ messages in thread
From: Greg KH @ 2019-01-10 19:15 UTC (permalink / raw)
  To: claudius.heine.ext; +Cc: stable, Bjorn Helgaas, Ley Foon Tan, Claudius Heine

On Mon, Jan 07, 2019 at 11:00:49AM +0100, claudius.heine.ext@siemens.com wrote:
> From: Claudius Heine <ch@denx.de>
> 
> Hi,
> 
> after a warm reboot, the altera pcie host interface is not correctly
> initialized in v4.4.
> 
> These patches from v4.9 solved that issue.

I only received 4 patches from this series for some reason.

Can you resend them all again?

Or just provide the git commit ids, if no backporting is needed.

thanks,

greg k-h

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

* Re: [PATCH v4.4 0/7] PCI: altera: survive warm reboot
  2019-01-10 19:15 ` [PATCH v4.4 0/7] PCI: altera: survive warm reboot Greg KH
@ 2019-01-14  8:24   ` Claudius Heine
  2019-01-14 17:40     ` Greg KH
  0 siblings, 1 reply; 12+ messages in thread
From: Claudius Heine @ 2019-01-14  8:24 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, Bjorn Helgaas, Ley Foon Tan, Claudius Heine

Hi Greg,

On 10/01/2019 20.15, Greg KH wrote:
> On Mon, Jan 07, 2019 at 11:00:49AM +0100, claudius.heine.ext@siemens.com wrote:
>> From: Claudius Heine <ch@denx.de>
>>
>> Hi,
>>
>> after a warm reboot, the altera pcie host interface is not correctly
>> initialized in v4.4.
>>
>> These patches from v4.9 solved that issue.
> 
> I only received 4 patches from this series for some reason.
> 
> Can you resend them all again?
> 
> Or just provide the git commit ids, if no backporting is needed.

Ok here are the commits:

eff31f4002c4e25b9b8c39d0a3a551c6c64c77e8 PCI: altera: Fix 
altera_pcie_link_is_up()
f8be11ae3d2c9a1338da37ff91ff4c65922d21be PCI: altera: Reorder read/write 
functions
c622032ebc538cb3869c312ae3ad235a99da84b6 PCI: altera: Check link status 
before retrain link
3a928e98a833e1a470a60d2fedf3c55502185fb7 PCI: altera: Poll for link up 
status after retraining the link
411dc32d8810e0a204c799ce5c97cb56990de1cb PCI: altera: Poll for link 
training status after retraining the link
31fc0ad47e2e0b8417616aa0f1ddcc67edf1e109 PCI: altera: Rework config 
accessors for use without a struct pci_bus
ce4f1c7ad490aa7129bde5632d6e53943f8a866c PCI: altera: Move retrain from 
fixup to altera_pcie_host_init()

Thanks,
Claudius

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-54 Fax: (+49)-8142-66989-80 Email: ch@denx.de

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

* Re: [PATCH v4.4 0/7] PCI: altera: survive warm reboot
  2019-01-14  8:24   ` Claudius Heine
@ 2019-01-14 17:40     ` Greg KH
  2019-01-15  8:34       ` Claudius Heine
  0 siblings, 1 reply; 12+ messages in thread
From: Greg KH @ 2019-01-14 17:40 UTC (permalink / raw)
  To: Claudius Heine; +Cc: stable, Bjorn Helgaas, Ley Foon Tan, Claudius Heine

On Mon, Jan 14, 2019 at 09:24:12AM +0100, Claudius Heine wrote:
> Hi Greg,
> 
> On 10/01/2019 20.15, Greg KH wrote:
> > On Mon, Jan 07, 2019 at 11:00:49AM +0100, claudius.heine.ext@siemens.com wrote:
> > > From: Claudius Heine <ch@denx.de>
> > > 
> > > Hi,
> > > 
> > > after a warm reboot, the altera pcie host interface is not correctly
> > > initialized in v4.4.
> > > 
> > > These patches from v4.9 solved that issue.
> > 
> > I only received 4 patches from this series for some reason.
> > 
> > Can you resend them all again?
> > 
> > Or just provide the git commit ids, if no backporting is needed.
> 
> Ok here are the commits:
> 
> eff31f4002c4e25b9b8c39d0a3a551c6c64c77e8 PCI: altera: Fix
> altera_pcie_link_is_up()
> f8be11ae3d2c9a1338da37ff91ff4c65922d21be PCI: altera: Reorder read/write
> functions
> c622032ebc538cb3869c312ae3ad235a99da84b6 PCI: altera: Check link status
> before retrain link
> 3a928e98a833e1a470a60d2fedf3c55502185fb7 PCI: altera: Poll for link up
> status after retraining the link
> 411dc32d8810e0a204c799ce5c97cb56990de1cb PCI: altera: Poll for link training
> status after retraining the link
> 31fc0ad47e2e0b8417616aa0f1ddcc67edf1e109 PCI: altera: Rework config
> accessors for use without a struct pci_bus
> ce4f1c7ad490aa7129bde5632d6e53943f8a866c PCI: altera: Move retrain from
> fixup to altera_pcie_host_init()

All now queued up.

But you really should move off of 4.4.y by now if you can, it's really
old, and 4.19 is much better.

thanks,

greg k-h

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

* Re: [PATCH v4.4 0/7] PCI: altera: survive warm reboot
  2019-01-14 17:40     ` Greg KH
@ 2019-01-15  8:34       ` Claudius Heine
  0 siblings, 0 replies; 12+ messages in thread
From: Claudius Heine @ 2019-01-15  8:34 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, Bjorn Helgaas, Ley Foon Tan, Claudius Heine

Hi Greg,

On 14/01/2019 18.40, Greg KH wrote:
> On Mon, Jan 14, 2019 at 09:24:12AM +0100, Claudius Heine wrote:
>> Hi Greg,
>>
>> On 10/01/2019 20.15, Greg KH wrote:
>>> On Mon, Jan 07, 2019 at 11:00:49AM +0100, claudius.heine.ext@siemens.com wrote:
>>>> From: Claudius Heine <ch@denx.de>
>>>>
>>>> Hi,
>>>>
>>>> after a warm reboot, the altera pcie host interface is not correctly
>>>> initialized in v4.4.
>>>>
>>>> These patches from v4.9 solved that issue.
>>>
>>> I only received 4 patches from this series for some reason.
>>>
>>> Can you resend them all again?
>>>
>>> Or just provide the git commit ids, if no backporting is needed.
>>
>> Ok here are the commits:
>>
>> eff31f4002c4e25b9b8c39d0a3a551c6c64c77e8 PCI: altera: Fix
>> altera_pcie_link_is_up()
>> f8be11ae3d2c9a1338da37ff91ff4c65922d21be PCI: altera: Reorder read/write
>> functions
>> c622032ebc538cb3869c312ae3ad235a99da84b6 PCI: altera: Check link status
>> before retrain link
>> 3a928e98a833e1a470a60d2fedf3c55502185fb7 PCI: altera: Poll for link up
>> status after retraining the link
>> 411dc32d8810e0a204c799ce5c97cb56990de1cb PCI: altera: Poll for link training
>> status after retraining the link
>> 31fc0ad47e2e0b8417616aa0f1ddcc67edf1e109 PCI: altera: Rework config
>> accessors for use without a struct pci_bus
>> ce4f1c7ad490aa7129bde5632d6e53943f8a866c PCI: altera: Move retrain from
>> fixup to altera_pcie_host_init()
> 
> All now queued up.
> 
> But you really should move off of 4.4.y by now if you can, it's really
> old, and 4.19 is much better.

Thanks! Yes I know, but some things are out of ones control :)

regards,
Claudius

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-54 Fax: (+49)-8142-66989-80 Email: ch@denx.de

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

end of thread, other threads:[~2019-01-15  8:35 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-07 10:00 [PATCH v4.4 0/7] PCI: altera: survive warm reboot claudius.heine.ext
2019-01-07 10:00 ` [PATCH v4.4 1/7] PCI: altera: Fix altera_pcie_link_is_up() claudius.heine.ext
2019-01-07 10:00 ` [PATCH v4.4 2/7] PCI: altera: Reorder read/write functions claudius.heine.ext
2019-01-07 10:00 ` [PATCH v4.4 3/7] PCI: altera: Check link status before retrain link claudius.heine.ext
2019-01-07 10:00 ` [PATCH v4.4 4/7] PCI: altera: Poll for link up status after retraining the link claudius.heine.ext
2019-01-07 10:00 ` [PATCH v4.4 5/7] PCI: altera: Poll for link training " claudius.heine.ext
2019-01-07 10:00 ` [PATCH v4.4 6/7] PCI: altera: Rework config accessors for use without a struct pci_bus claudius.heine.ext
2019-01-07 10:00 ` [PATCH v4.4 7/7] PCI: altera: Move retrain from fixup to altera_pcie_host_init() claudius.heine.ext
2019-01-10 19:15 ` [PATCH v4.4 0/7] PCI: altera: survive warm reboot Greg KH
2019-01-14  8:24   ` Claudius Heine
2019-01-14 17:40     ` Greg KH
2019-01-15  8:34       ` Claudius Heine

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.