mvebu: sort patches
[openwrt/openwrt.git] / target / linux / mvebu / patches-5.4 / 405-PCI-aardvark-Improve-link-training.patch
diff --git a/target/linux/mvebu/patches-5.4/405-PCI-aardvark-Improve-link-training.patch b/target/linux/mvebu/patches-5.4/405-PCI-aardvark-Improve-link-training.patch
deleted file mode 100644 (file)
index 2bf8384..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-From 43fc679ced18006b12d918d7a8a4af392b7fbfe7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@nic.cz>
-Date: Thu, 30 Apr 2020 10:06:17 +0200
-Subject: [PATCH] PCI: aardvark: Improve link training
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently the aardvark driver trains link in PCIe gen2 mode. This may
-cause some buggy gen1 cards (such as Compex WLE900VX) to be unstable or
-even not detected. Moreover when ASPM code tries to retrain link second
-time, these cards may stop responding and link goes down. If gen1 is
-used this does not happen.
-
-Unconditionally forcing gen1 is not a good solution since it may have
-performance impact on gen2 cards.
-
-To overcome this, read 'max-link-speed' property (as defined in PCI
-device tree bindings) and use this as max gen mode. Then iteratively try
-link training at this mode or lower until successful. After successful
-link training choose final controller gen based on Negotiated Link Speed
-from Link Status register, which should match card speed.
-
-Link: https://lore.kernel.org/r/20200430080625.26070-5-pali@kernel.org
-Tested-by: Tomasz Maciej Nowak <tmn505@gmail.com>
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Signed-off-by: Marek Behún <marek.behun@nic.cz>
-Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Acked-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
----
- drivers/pci/controller/pci-aardvark.c | 114 ++++++++++++++++++++------
- 1 file changed, 89 insertions(+), 25 deletions(-)
-
---- a/drivers/pci/controller/pci-aardvark.c
-+++ b/drivers/pci/controller/pci-aardvark.c
-@@ -39,6 +39,7 @@
- #define PCIE_CORE_LINK_CTRL_STAT_REG                          0xd0
- #define     PCIE_CORE_LINK_L0S_ENTRY                          BIT(0)
- #define     PCIE_CORE_LINK_TRAINING                           BIT(5)
-+#define     PCIE_CORE_LINK_SPEED_SHIFT                                16
- #define     PCIE_CORE_LINK_WIDTH_SHIFT                                20
- #define PCIE_CORE_ERR_CAPCTL_REG                              0x118
- #define     PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX                  BIT(5)
-@@ -201,6 +202,7 @@ struct advk_pcie {
-       struct mutex msi_used_lock;
-       u16 msi_msg;
-       int root_bus_nr;
-+      int link_gen;
-       struct pci_bridge_emul bridge;
- };
-@@ -225,20 +227,16 @@ static int advk_pcie_link_up(struct advk
- static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
- {
--      struct device *dev = &pcie->pdev->dev;
-       int retries;
-       /* check if the link is up or not */
-       for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
--              if (advk_pcie_link_up(pcie)) {
--                      dev_info(dev, "link up\n");
-+              if (advk_pcie_link_up(pcie))
-                       return 0;
--              }
-               usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
-       }
--      dev_err(dev, "link never came up\n");
-       return -ETIMEDOUT;
- }
-@@ -253,6 +251,85 @@ static void advk_pcie_wait_for_retrain(s
-       }
- }
-+static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen)
-+{
-+      int ret, neg_gen;
-+      u32 reg;
-+
-+      /* Setup link speed */
-+      reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
-+      reg &= ~PCIE_GEN_SEL_MSK;
-+      if (gen == 3)
-+              reg |= SPEED_GEN_3;
-+      else if (gen == 2)
-+              reg |= SPEED_GEN_2;
-+      else
-+              reg |= SPEED_GEN_1;
-+      advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
-+
-+      /*
-+       * Enable link training. This is not needed in every call to this
-+       * function, just once suffices, but it does not break anything either.
-+       */
-+      reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
-+      reg |= LINK_TRAINING_EN;
-+      advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
-+
-+      /*
-+       * Start link training immediately after enabling it.
-+       * This solves problems for some buggy cards.
-+       */
-+      reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
-+      reg |= PCIE_CORE_LINK_TRAINING;
-+      advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
-+
-+      ret = advk_pcie_wait_for_link(pcie);
-+      if (ret)
-+              return ret;
-+
-+      reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
-+      neg_gen = (reg >> PCIE_CORE_LINK_SPEED_SHIFT) & 0xf;
-+
-+      return neg_gen;
-+}
-+
-+static void advk_pcie_train_link(struct advk_pcie *pcie)
-+{
-+      struct device *dev = &pcie->pdev->dev;
-+      int neg_gen = -1, gen;
-+
-+      /*
-+       * Try link training at link gen specified by device tree property
-+       * 'max-link-speed'. If this fails, iteratively train at lower gen.
-+       */
-+      for (gen = pcie->link_gen; gen > 0; --gen) {
-+              neg_gen = advk_pcie_train_at_gen(pcie, gen);
-+              if (neg_gen > 0)
-+                      break;
-+      }
-+
-+      if (neg_gen < 0)
-+              goto err;
-+
-+      /*
-+       * After successful training if negotiated gen is lower than requested,
-+       * train again on negotiated gen. This solves some stability issues for
-+       * some buggy gen1 cards.
-+       */
-+      if (neg_gen < gen) {
-+              gen = neg_gen;
-+              neg_gen = advk_pcie_train_at_gen(pcie, gen);
-+      }
-+
-+      if (neg_gen == gen) {
-+              dev_info(dev, "link up at gen %i\n", gen);
-+              return;
-+      }
-+
-+err:
-+      dev_err(dev, "link never came up\n");
-+}
-+
- static void advk_pcie_setup_hw(struct advk_pcie *pcie)
- {
-       u32 reg;
-@@ -288,12 +365,6 @@ static void advk_pcie_setup_hw(struct ad
-               PCIE_CORE_CTRL2_TD_ENABLE;
-       advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
--      /* Set GEN2 */
--      reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
--      reg &= ~PCIE_GEN_SEL_MSK;
--      reg |= SPEED_GEN_2;
--      advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
--
-       /* Set lane X1 */
-       reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
-       reg &= ~LANE_CNT_MSK;
-@@ -341,20 +412,7 @@ static void advk_pcie_setup_hw(struct ad
-        */
-       msleep(PCI_PM_D3COLD_WAIT);
--      /* Enable link training */
--      reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
--      reg |= LINK_TRAINING_EN;
--      advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
--
--      /*
--       * Start link training immediately after enabling it.
--       * This solves problems for some buggy cards.
--       */
--      reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
--      reg |= PCIE_CORE_LINK_TRAINING;
--      advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
--
--      advk_pcie_wait_for_link(pcie);
-+      advk_pcie_train_link(pcie);
-       reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
-       reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
-@@ -1035,6 +1093,12 @@ static int advk_pcie_probe(struct platfo
-               return ret;
-       }
-+      ret = of_pci_get_max_link_speed(dev->of_node);
-+      if (ret <= 0 || ret > 3)
-+              pcie->link_gen = 3;
-+      else
-+              pcie->link_gen = ret;
-+
-       advk_pcie_setup_hw(pcie);
-       ret = advk_sw_pci_bridge_init(pcie);