ramips: mt7621: backport PCIe driver fixes from staging-test
authorDENG Qingfang <dengqf6@mail2.sysu.edu.cn>
Wed, 11 Mar 2020 13:05:41 +0000 (21:05 +0800)
committerChuanhong Guo <gch981213@gmail.com>
Sat, 4 Apr 2020 06:14:43 +0000 (14:14 +0800)
Backport mt7621-pci/mt7621-pci-phy fixes from staging-test

Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
20 files changed:
target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch [new file with mode: 0644]
target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch [new file with mode: 0644]

diff --git a/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch b/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch
new file mode 100644 (file)
index 0000000..b9bcd63
--- /dev/null
@@ -0,0 +1,133 @@
+From b327cd58c3fec1c6382128e929eab9bc0d68e912 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sun, 8 Mar 2020 10:19:27 +0100
+Subject: [PATCH] staging: mt7621-pci: simplify
+ 'mt7621_pcie_init_virtual_bridges' function
+
+Function 'mt7621_pcie_init_virtual_bridges' is a bit mess and can be
+refactorized properly in a cleaner way. Introduce new 'pcie_rmw' inline
+function helper to do clear and set the correct bits this function needs
+to work.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200308091928.17177-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 85 +++++++++++++--------------------
+ 1 file changed, 33 insertions(+), 52 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -57,13 +57,13 @@
+ #define RALINK_PCI_IOBASE             0x002C
+ /* PCICFG virtual bridges */
+-#define MT7621_BR0_MASK                       GENMASK(19, 16)
+-#define MT7621_BR1_MASK                       GENMASK(23, 20)
+-#define MT7621_BR2_MASK                       GENMASK(27, 24)
+-#define MT7621_BR_ALL_MASK            GENMASK(27, 16)
+-#define MT7621_BR0_SHIFT              16
+-#define MT7621_BR1_SHIFT              20
+-#define MT7621_BR2_SHIFT              24
++#define PCIE_P2P_MAX                  3
++#define PCIE_P2P_BR_DEVNUM_SHIFT(p)   (16 + (p) * 4)
++#define PCIE_P2P_BR_DEVNUM0_SHIFT     PCIE_P2P_BR_DEVNUM_SHIFT(0)
++#define PCIE_P2P_BR_DEVNUM1_SHIFT     PCIE_P2P_BR_DEVNUM_SHIFT(1)
++#define PCIE_P2P_BR_DEVNUM2_SHIFT     PCIE_P2P_BR_DEVNUM_SHIFT(2)
++#define PCIE_P2P_BR_DEVNUM_MASK               0xf
++#define PCIE_P2P_BR_DEVNUM_MASK_FULL  (0xfff << PCIE_P2P_BR_DEVNUM0_SHIFT)
+ /* PCIe RC control registers */
+ #define MT7621_PCIE_OFFSET            0x2000
+@@ -154,6 +154,15 @@ static inline void pcie_write(struct mt7
+       writel(val, pcie->base + reg);
+ }
++static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set)
++{
++      u32 val = readl(pcie->base + reg);
++
++      val &= ~clr;
++      val |= set;
++      writel(val, pcie->base + reg);
++}
++
+ static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg)
+ {
+       return readl(port->base + reg);
+@@ -554,7 +563,9 @@ static void mt7621_pcie_enable_ports(str
+ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie)
+ {
+       u32 pcie_link_status = 0;
+-      u32 val = 0;
++      u32 n;
++      int i;
++      u32 p2p_br_devnum[PCIE_P2P_MAX];
+       struct mt7621_pcie_port *port;
+       list_for_each_entry(port, &pcie->ports, list) {
+@@ -567,50 +578,20 @@ static int mt7621_pcie_init_virtual_brid
+       if (pcie_link_status == 0)
+               return -1;
+-      /*
+-       * pcie(2/1/0) link status      pcie2_num       pcie1_num       pcie0_num
+-       * 3'b000                       x               x               x
+-       * 3'b001                       x               x               0
+-       * 3'b010                       x               0               x
+-       * 3'b011                       x               1               0
+-       * 3'b100                       0               x               x
+-       * 3'b101                       1               x               0
+-       * 3'b110                       1               0               x
+-       * 3'b111                       2               1               0
+-       */
+-      switch (pcie_link_status) {
+-      case 2:
+-              val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-              val &= ~(MT7621_BR0_MASK | MT7621_BR1_MASK);
+-              val |= 0x1 << MT7621_BR0_SHIFT;
+-              val |= 0x0 << MT7621_BR1_SHIFT;
+-              pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-              break;
+-      case 4:
+-              val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-              val &= ~MT7621_BR_ALL_MASK;
+-              val |= 0x1 << MT7621_BR0_SHIFT;
+-              val |= 0x2 << MT7621_BR1_SHIFT;
+-              val |= 0x0 << MT7621_BR2_SHIFT;
+-              pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-              break;
+-      case 5:
+-              val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-              val &= ~MT7621_BR_ALL_MASK;
+-              val |= 0x0 << MT7621_BR0_SHIFT;
+-              val |= 0x2 << MT7621_BR1_SHIFT;
+-              val |= 0x1 << MT7621_BR2_SHIFT;
+-              pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-              break;
+-      case 6:
+-              val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-              val &= ~MT7621_BR_ALL_MASK;
+-              val |= 0x2 << MT7621_BR0_SHIFT;
+-              val |= 0x0 << MT7621_BR1_SHIFT;
+-              val |= 0x1 << MT7621_BR2_SHIFT;
+-              pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-              break;
+-      }
++      n = 0;
++      for (i = 0; i < PCIE_P2P_MAX; i++)
++              if (pcie_link_status & BIT(i))
++                      p2p_br_devnum[i] = n++;
++
++      for (i = 0; i < PCIE_P2P_MAX; i++)
++              if ((pcie_link_status & BIT(i)) == 0)
++                      p2p_br_devnum[i] = n++;
++
++      pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR,
++               PCIE_P2P_BR_DEVNUM_MASK_FULL,
++               (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) |
++               (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
++               (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT));
+       return 0;
+ }
diff --git a/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch b/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch
new file mode 100644 (file)
index 0000000..3939280
--- /dev/null
@@ -0,0 +1,74 @@
+From 550fabd71d7fcdfe099bbf41e00e28719737161e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Tue, 10 Mar 2020 12:34:59 +0100
+Subject: [PATCH] staging: mt7621-pci: enable clock bit for each port
+
+The clock related code concerns me from the very beginning because
+there are some set ups got from legacy driver that are not documented
+anywhere. According to the programming guide 0x7c is 'CPE_ROSC_SEL1'
+register and 0x80 is 'CPU_CPE_CN'. I do think this set up is not needed
+at all and the proper thing to do is just enable the clock bit for each
+pcie port. Hence remove useless code and do the right thing which is
+setting up the clock bit for each port enabled.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200310113459.30539-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -45,8 +45,6 @@
+ /* rt_sysc_membase relative registers */
+ #define RALINK_CLKCFG1                        0x30
+-#define RALINK_PCIE_CLK_GEN           0x7c
+-#define RALINK_PCIE_CLK_GEN1          0x80
+ /* Host-PCI bridge registers */
+ #define RALINK_PCI_PCICFG_ADDR                0x0000
+@@ -85,10 +83,6 @@
+ #define PCIE_PORT_CLK_EN(x)           BIT(24 + (x))
+ #define PCIE_PORT_LINKUP              BIT(0)
+-#define PCIE_CLK_GEN_EN                       BIT(31)
+-#define PCIE_CLK_GEN_DIS              0
+-#define PCIE_CLK_GEN1_DIS             GENMASK(30, 24)
+-#define PCIE_CLK_GEN1_EN              (BIT(27) | BIT(25))
+ #define MEMORY_BASE                   0x0
+ #define PERST_MODE_MASK                       GENMASK(11, 10)
+ #define PERST_MODE_GPIO                       BIT(10)
+@@ -233,6 +227,11 @@ static inline bool mt7621_pcie_port_is_l
+       return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0;
+ }
++static inline void mt7621_pcie_port_clk_enable(struct mt7621_pcie_port *port)
++{
++      rt_sysc_m32(0, PCIE_PORT_CLK_EN(port->slot), RALINK_CLKCFG1);
++}
++
+ static inline void mt7621_pcie_port_clk_disable(struct mt7621_pcie_port *port)
+ {
+       rt_sysc_m32(PCIE_PORT_CLK_EN(port->slot), 0, RALINK_CLKCFG1);
+@@ -501,11 +500,6 @@ static void mt7621_pcie_init_ports(struc
+               }
+       }
+-      rt_sysc_m32(0x30, 2 << 4, SYSC_REG_SYSTEM_CONFIG1);
+-      rt_sysc_m32(PCIE_CLK_GEN_EN, PCIE_CLK_GEN_DIS, RALINK_PCIE_CLK_GEN);
+-      rt_sysc_m32(PCIE_CLK_GEN1_DIS, PCIE_CLK_GEN1_EN, RALINK_PCIE_CLK_GEN1);
+-      rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN);
+-      msleep(50);
+       reset_control_deassert(pcie->rst);
+ }
+@@ -542,6 +536,7 @@ static void mt7621_pcie_enable_ports(str
+       list_for_each_entry(port, &pcie->ports, list) {
+               if (port->enabled) {
++                      mt7621_pcie_port_clk_enable(port);
+                       mt7621_pcie_enable_port(port);
+                       dev_info(dev, "PCIE%d enabled\n", num_slots_enabled);
+                       num_slots_enabled++;
diff --git a/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch b/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch
new file mode 100644 (file)
index 0000000..1b7828f
--- /dev/null
@@ -0,0 +1,222 @@
+From 227a8bf421ff8b085444e51e471ef06a87228cfd Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:08 +0100
+Subject: [PATCH] staging: mt7621-pci: use gpios for properly reset
+
+Original driver code was using three gpio's for reset
+asserts and deasserts the pcis. Instead of using that
+a general reset control with a perst gpio was introduced
+and it seems it is partially working but sometimes there
+are some unexpected hangs on boot. This commit make use of
+the three original gpios using 'reset-gpios' property of
+the device tree and removes the reset line and perst gpio.
+According to the mediatek aplication note v0.1 there are
+three gpios used for pcie ports reset control: gpio#19,
+gpio#8 and gpio#7 for slots 0, 1 and 2 respectively.
+This schema can be used separately for mt7621A but in some
+boards due to pin share issue, if the PCM and I2S function
+are enable at the same time, there are no enough GPIO to
+control per-port PCIe reset. In those cases gpio#19 is enought
+for reset the three ports together. Because of this we just
+try to get the three gpios but if some of them fail we are not
+failing in boot process, just prints a kernel notice and take
+after into account if the descriptor is or not valid in order
+to use it. All of them are set as GPIO output low configuration.
+The gpio descriptor's API takes device tree property into account
+and invert value if the pin is configured as active low.
+So we also have to properly request pins from device tree
+and set values correct in assert and deassert functions.
+After this changes the order to make all assert and
+deassert in the 'probe' process makes more sense:
+* Parse device tree.
+* make assert of the RC's and EP's before doing anything else.
+* make deassert of the RC's before initializing the phy.
+* Init the phy.
+* make deassert of the EP's before initialize pci ports.
+* Normal PCI initialization.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-2-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 84 ++++++++++++++++++++-------------
+ 1 file changed, 51 insertions(+), 33 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -95,6 +95,7 @@
+  * @pcie: pointer to PCIe host info
+  * @phy: pointer to PHY control block
+  * @pcie_rst: pointer to port reset control
++ * @gpio_rst: gpio reset
+  * @slot: port slot
+  * @enabled: indicates if port is enabled
+  */
+@@ -104,6 +105,7 @@ struct mt7621_pcie_port {
+       struct mt7621_pcie *pcie;
+       struct phy *phy;
+       struct reset_control *pcie_rst;
++      struct gpio_desc *gpio_rst;
+       u32 slot;
+       bool enabled;
+ };
+@@ -117,8 +119,6 @@ struct mt7621_pcie_port {
+  * @offset: IO / Memory offset
+  * @dev: Pointer to PCIe device
+  * @ports: pointer to PCIe port information
+- * @perst: gpio reset
+- * @rst: pointer to pcie reset
+  * @resets_inverted: depends on chip revision
+  * reset lines are inverted.
+  */
+@@ -133,8 +133,6 @@ struct mt7621_pcie {
+               resource_size_t io;
+       } offset;
+       struct list_head ports;
+-      struct gpio_desc *perst;
+-      struct reset_control *rst;
+       bool resets_inverted;
+ };
+@@ -210,16 +208,16 @@ static void write_config(struct mt7621_p
+       pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA);
+ }
+-static inline void mt7621_perst_gpio_pcie_assert(struct mt7621_pcie *pcie)
++static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port)
+ {
+-      gpiod_set_value(pcie->perst, 0);
+-      mdelay(PERST_DELAY_US);
++      if (port->gpio_rst)
++              gpiod_set_value(port->gpio_rst, 1);
+ }
+-static inline void mt7621_perst_gpio_pcie_deassert(struct mt7621_pcie *pcie)
++static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port)
+ {
+-      gpiod_set_value(pcie->perst, 1);
+-      mdelay(PERST_DELAY_US);
++      if (port->gpio_rst)
++              gpiod_set_value(port->gpio_rst, 0);
+ }
+ static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port)
+@@ -367,6 +365,13 @@ static int mt7621_pcie_parse_port(struct
+       if (IS_ERR(port->phy))
+               return PTR_ERR(port->phy);
++      port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
++                                                     GPIOD_OUT_LOW);
++      if (IS_ERR(port->gpio_rst)) {
++              dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
++              return PTR_ERR(port->gpio_rst);
++      }
++
+       port->slot = slot;
+       port->pcie = pcie;
+@@ -383,12 +388,6 @@ static int mt7621_pcie_parse_dt(struct m
+       struct resource regs;
+       int err;
+-      pcie->perst = devm_gpiod_get(dev, "perst", GPIOD_OUT_HIGH);
+-      if (IS_ERR(pcie->perst)) {
+-              dev_err(dev, "failed to get gpio perst\n");
+-              return PTR_ERR(pcie->perst);
+-      }
+-
+       err = of_address_to_resource(node, 0, &regs);
+       if (err) {
+               dev_err(dev, "missing \"reg\" property\n");
+@@ -399,12 +398,6 @@ static int mt7621_pcie_parse_dt(struct m
+       if (IS_ERR(pcie->base))
+               return PTR_ERR(pcie->base);
+-      pcie->rst = devm_reset_control_get_exclusive(dev, "pcie");
+-      if (PTR_ERR(pcie->rst) == -EPROBE_DEFER) {
+-              dev_err(dev, "failed to get pcie reset control\n");
+-              return PTR_ERR(pcie->rst);
+-      }
+-
+       for_each_available_child_of_node(node, child) {
+               int slot;
+@@ -458,16 +451,49 @@ static int mt7621_pcie_init_port(struct
+       return 0;
+ }
++static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie)
++{
++      struct mt7621_pcie_port *port;
++
++      list_for_each_entry(port, &pcie->ports, list) {
++              /* PCIe RC reset assert */
++              mt7621_control_assert(port);
++
++              /* PCIe EP reset assert */
++              mt7621_rst_gpio_pcie_assert(port);
++      }
++
++      mdelay(PERST_DELAY_US);
++}
++
++static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie)
++{
++      struct mt7621_pcie_port *port;
++
++      list_for_each_entry(port, &pcie->ports, list)
++              mt7621_control_deassert(port);
++}
++
++static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie)
++{
++      struct mt7621_pcie_port *port;
++
++      list_for_each_entry(port, &pcie->ports, list)
++              mt7621_rst_gpio_pcie_deassert(port);
++
++      mdelay(PERST_DELAY_US);
++}
++
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
+ {
+       struct device *dev = pcie->dev;
+       struct mt7621_pcie_port *port, *tmp;
+-      u32 val = 0;
+       int err;
+       rt_sysc_m32(PERST_MODE_MASK, PERST_MODE_GPIO, MT7621_GPIO_MODE);
+-      mt7621_perst_gpio_pcie_assert(pcie);
++      mt7621_pcie_reset_assert(pcie);
++      mt7621_pcie_reset_rc_deassert(pcie);
+       list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+               u32 slot = port->slot;
+@@ -476,16 +502,10 @@ static void mt7621_pcie_init_ports(struc
+               if (err) {
+                       dev_err(dev, "Initiating port %d failed\n", slot);
+                       list_del(&port->list);
+-              } else {
+-                      val = read_config(pcie, slot, PCIE_FTS_NUM);
+-                      dev_info(dev, "Port %d N_FTS = %x\n", slot,
+-                               (unsigned int)val);
+               }
+       }
+-      reset_control_assert(pcie->rst);
+-
+-      mt7621_perst_gpio_pcie_deassert(pcie);
++      mt7621_pcie_reset_ep_deassert(pcie);
+       list_for_each_entry(port, &pcie->ports, list) {
+               u32 slot = port->slot;
+@@ -499,8 +519,6 @@ static void mt7621_pcie_init_ports(struc
+                       port->enabled = false;
+               }
+       }
+-
+-      reset_control_deassert(pcie->rst);
+ }
+ static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
diff --git a/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch b/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch
new file mode 100644 (file)
index 0000000..3d86355
--- /dev/null
@@ -0,0 +1,45 @@
+From e462e7d3211479df42357a620fa788a2257556b7 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:09 +0100
+Subject: [PATCH] staging: mt7621-pci: change value for 'PERST_DELAY_MS'
+
+Value of 'PERST_DELAY_MS' is too high and it is ok just
+to set up to 100 ms. Update also define name from
+'PERST_DELAY_US' into 'PERST_DELAY_MS'
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-3-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -86,7 +86,7 @@
+ #define MEMORY_BASE                   0x0
+ #define PERST_MODE_MASK                       GENMASK(11, 10)
+ #define PERST_MODE_GPIO                       BIT(10)
+-#define PERST_DELAY_US                        1000
++#define PERST_DELAY_MS                        100
+ /**
+  * struct mt7621_pcie_port - PCIe port information
+@@ -463,7 +463,7 @@ static void mt7621_pcie_reset_assert(str
+               mt7621_rst_gpio_pcie_assert(port);
+       }
+-      mdelay(PERST_DELAY_US);
++      mdelay(PERST_DELAY_MS);
+ }
+ static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie)
+@@ -481,7 +481,7 @@ static void mt7621_pcie_reset_ep_deasser
+       list_for_each_entry(port, &pcie->ports, list)
+               mt7621_rst_gpio_pcie_deassert(port);
+-      mdelay(PERST_DELAY_US);
++      mdelay(PERST_DELAY_MS);
+ }
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
diff --git a/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch b/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch
new file mode 100644 (file)
index 0000000..f24bf83
--- /dev/null
@@ -0,0 +1,76 @@
+From 4d6a758f2cd2122a7d895f913854c13da62ba6df Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:12 +0100
+Subject: [PATCH] staging: mt7621-pci: release gpios after pci initialization
+
+R3G's LEDs fail to initialize because one of them uses GPIO8
+Hence, release the GPIO resources after PCIe initialization
+and properly release also in driver error path.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-6-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -484,6 +484,15 @@ static void mt7621_pcie_reset_ep_deasser
+       mdelay(PERST_DELAY_MS);
+ }
++static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie)
++{
++      struct mt7621_pcie_port *port;
++
++      list_for_each_entry(port, &pcie->ports, list)
++              if (port->gpio_rst)
++                      gpiod_put(port->gpio_rst);
++}
++
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
+ {
+       struct device *dev = pcie->dev;
+@@ -683,7 +692,8 @@ static int mt7621_pci_probe(struct platf
+       err = mt7621_pcie_init_virtual_bridges(pcie);
+       if (err) {
+               dev_err(dev, "Nothing is connected in virtual bridges. Exiting...");
+-              return 0;
++              err = 0;
++              goto out_release_gpios;
+       }
+       mt7621_pcie_enable_ports(pcie);
+@@ -691,7 +701,7 @@ static int mt7621_pci_probe(struct platf
+       err = mt7621_pci_parse_request_of_pci_ranges(pcie);
+       if (err) {
+               dev_err(dev, "Error requesting pci resources from ranges");
+-              return err;
++              goto out_release_gpios;
+       }
+       setup_cm_memory_region(pcie);
+@@ -699,16 +709,19 @@ static int mt7621_pci_probe(struct platf
+       err = mt7621_pcie_request_resources(pcie, &res);
+       if (err) {
+               dev_err(dev, "Error requesting resources\n");
+-              return err;
++              goto out_release_gpios;
+       }
+       err = mt7621_pcie_register_host(bridge, &res);
+       if (err) {
+               dev_err(dev, "Error registering host\n");
+-              return err;
++              goto out_release_gpios;
+       }
+-      return 0;
++out_release_gpios:
++      mt7621_pcie_release_gpios(pcie);
++
++      return err;
+ }
+ static const struct of_device_id mt7621_pci_ids[] = {
diff --git a/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch b/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch
new file mode 100644 (file)
index 0000000..fc509e9
--- /dev/null
@@ -0,0 +1,46 @@
+From 4be54c3a495f08c05a8e485566e5b88cd3537f16 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:13 +0100
+Subject: [PATCH] staging: mt7621-pci: delete no more needed
+ 'mt7621_reset_port'
+
+After review all the resets at the beggining the function
+'mt7621_reset_port' is not needed anymore. Hence delete it
+and its uses.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-7-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -255,13 +255,6 @@ static inline void mt7621_control_deasse
+               reset_control_assert(port->pcie_rst);
+ }
+-static void mt7621_reset_port(struct mt7621_pcie_port *port)
+-{
+-      mt7621_control_assert(port);
+-      msleep(100);
+-      mt7621_control_deassert(port);
+-}
+-
+ static void setup_cm_memory_region(struct mt7621_pcie *pcie)
+ {
+       struct resource *mem_resource = &pcie->mem;
+@@ -427,12 +420,6 @@ static int mt7621_pcie_init_port(struct
+       u32 slot = port->slot;
+       int err;
+-      /*
+-       * Any MT7621 Ralink pcie controller that doesn't have 0x0101 at
+-       * the end of the chip_id has inverted PCI resets.
+-       */
+-      mt7621_reset_port(port);
+-
+       err = phy_init(port->phy);
+       if (err) {
+               dev_err(dev, "failed to initialize port%d phy\n", slot);
diff --git a/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch b/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch
new file mode 100644 (file)
index 0000000..234af32
--- /dev/null
@@ -0,0 +1,234 @@
+From bf0c6782e5b9a6deee4e223655325dc004fae8dd Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sun, 15 Mar 2020 17:01:54 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: add 'mt7621_phy_rmw' to simplify
+ code
+
+In order to simplify driver code and decrease a bit LOC add new
+function 'mt7621_phy_rmw' where clear and set bits are passed as
+arguments.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200315160154.10292-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 158 +++++++++++-------------
+ 1 file changed, 71 insertions(+), 87 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -120,17 +120,25 @@ static inline void phy_write(struct mt76
+       regmap_write(phy->regmap, reg, val);
+ }
++static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy,
++                                u32 reg, u32 clr, u32 set)
++{
++      u32 val = phy_read(phy, reg);
++
++      val &= ~clr;
++      val |= set;
++      phy_write(phy, val, reg);
++}
++
+ static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy,
+                                  struct mt7621_pci_phy_instance *instance)
+ {
+       u32 offset = (instance->index != 1) ?
+               RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH;
+-      u32 reg;
+-      reg = phy_read(phy, offset);
+-      reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
+-      reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
+-      phy_write(phy, reg, offset);
++      mt7621_phy_rmw(phy, offset,
++                     RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC,
++                     RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
+ }
+ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy,
+@@ -139,97 +147,77 @@ static void mt7621_set_phy_for_ssc(struc
+       struct device *dev = phy->dev;
+       u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+       u32 offset;
+-      u32 val;
+       reg = (reg >> 6) & 0x7;
+       /* Set PCIe Port PHY to disable SSC */
+       /* Debug Xtal Type */
+-      val = phy_read(phy, RG_PE1_FRC_H_XTAL_REG);
+-      val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE);
+-      val |= RG_PE1_FRC_H_XTAL_TYPE;
+-      val |= RG_PE1_H_XTAL_TYPE_VAL(0x00);
+-      phy_write(phy, val, RG_PE1_FRC_H_XTAL_REG);
++      mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
++                     RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE,
++                     RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00));
+       /* disable port */
+       offset = (instance->index != 1) ?
+               RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-      val = phy_read(phy, offset);
+-      val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-      val |= RG_PE1_FRC_PHY_EN;
+-      phy_write(phy, val, offset);
+-
+-      /* Set Pre-divider ratio (for host mode) */
+-      val = phy_read(phy, RG_PE1_H_PLL_REG);
+-      val &= ~(RG_PE1_H_PLL_PREDIV);
++      mt7621_phy_rmw(phy, offset,
++                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
+       if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
+-              val |= RG_PE1_H_PLL_PREDIV_VAL(0x01);
+-              phy_write(phy, val, RG_PE1_H_PLL_REG);
++              /* Set Pre-divider ratio (for host mode) */
++              mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++                             RG_PE1_H_PLL_PREDIV,
++                             RG_PE1_H_PLL_PREDIV_VAL(0x01));
+               dev_info(dev, "Xtal is 40MHz\n");
+-      } else { /* 25MHz | 20MHz Xtal */
+-              val |= RG_PE1_H_PLL_PREDIV_VAL(0x00);
+-              phy_write(phy, val, RG_PE1_H_PLL_REG);
+-              if (reg >= 6) {
+-                      dev_info(dev, "Xtal is 25MHz\n");
+-
+-                      /* Select feedback clock */
+-                      val = phy_read(phy, RG_PE1_H_PLL_FBKSEL_REG);
+-                      val &= ~(RG_PE1_H_PLL_FBKSEL);
+-                      val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01);
+-                      phy_write(phy, val, RG_PE1_H_PLL_FBKSEL_REG);
+-
+-                      /* DDS NCPO PCW (for host mode) */
+-                      val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-                      val &= ~(RG_PE1_H_LCDDS_SSC_PRD);
+-                      val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000);
+-                      phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-
+-                      /* DDS SSC dither period control */
+-                      val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-                      val &= ~(RG_PE1_H_LCDDS_SSC_PRD);
+-                      val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d);
+-                      phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-
+-                      /* DDS SSC dither amplitude control */
+-                      val = phy_read(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG);
+-                      val &= ~(RG_PE1_H_LCDDS_SSC_DELTA |
+-                               RG_PE1_H_LCDDS_SSC_DELTA1);
+-                      val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a);
+-                      val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a);
+-                      phy_write(phy, val, RG_PE1_H_LCDDS_SSC_DELTA_REG);
+-              } else {
+-                      dev_info(dev, "Xtal is 20MHz\n");
+-              }
++      } else if (reg >= 6) { /* 25MHz Xal */
++              mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++                             RG_PE1_H_PLL_PREDIV,
++                             RG_PE1_H_PLL_PREDIV_VAL(0x00));
++              /* Select feedback clock */
++              mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG,
++                             RG_PE1_H_PLL_FBKSEL,
++                             RG_PE1_H_PLL_FBKSEL_VAL(0x01));
++              /* DDS NCPO PCW (for host mode) */
++              mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
++                             RG_PE1_H_LCDDS_SSC_PRD,
++                             RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000));
++              /* DDS SSC dither period control */
++              mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
++                             RG_PE1_H_LCDDS_SSC_PRD,
++                             RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d));
++              /* DDS SSC dither amplitude control */
++              mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG,
++                             RG_PE1_H_LCDDS_SSC_DELTA |
++                             RG_PE1_H_LCDDS_SSC_DELTA1,
++                             RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a) |
++                             RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a));
++              dev_info(dev, "Xtal is 25MHz\n");
++      } else { /* 20MHz Xtal */
++              mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++                             RG_PE1_H_PLL_PREDIV,
++                             RG_PE1_H_PLL_PREDIV_VAL(0x00));
++
++              dev_info(dev, "Xtal is 20MHz\n");
+       }
+       /* DDS clock inversion */
+-      val = phy_read(phy, RG_PE1_LCDDS_CLK_PH_INV_REG);
+-      val &= ~(RG_PE1_LCDDS_CLK_PH_INV);
+-      val |= RG_PE1_LCDDS_CLK_PH_INV;
+-      phy_write(phy, val, RG_PE1_LCDDS_CLK_PH_INV_REG);
++      mt7621_phy_rmw(phy, RG_PE1_LCDDS_CLK_PH_INV_REG,
++                     RG_PE1_LCDDS_CLK_PH_INV, RG_PE1_LCDDS_CLK_PH_INV);
+       /* Set PLL bits */
+-      val = phy_read(phy, RG_PE1_H_PLL_REG);
+-      val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
+-               RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN);
+-      val |= RG_PE1_H_PLL_BC_VAL(0x02);
+-      val |= RG_PE1_H_PLL_BP_VAL(0x06);
+-      val |= RG_PE1_H_PLL_IR_VAL(0x02);
+-      val |= RG_PE1_H_PLL_IC_VAL(0x01);
+-      val |= RG_PE1_PLL_DIVEN_VAL(0x02);
+-      phy_write(phy, val, RG_PE1_H_PLL_REG);
+-
+-      val = phy_read(phy, RG_PE1_H_PLL_BR_REG);
+-      val &= ~(RG_PE1_H_PLL_BR);
+-      val |= RG_PE1_H_PLL_BR_VAL(0x00);
+-      phy_write(phy, val, RG_PE1_H_PLL_BR_REG);
++      mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++                     RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
++                     RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN,
++                     RG_PE1_H_PLL_BC_VAL(0x02) | RG_PE1_H_PLL_BP_VAL(0x06) |
++                     RG_PE1_H_PLL_IR_VAL(0x02) | RG_PE1_H_PLL_IC_VAL(0x01) |
++                     RG_PE1_PLL_DIVEN_VAL(0x02));
++
++      mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG,
++                     RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00));
+       if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
+               /* set force mode enable of da_pe1_mstckdiv */
+-              val = phy_read(phy, RG_PE1_MSTCKDIV_REG);
+-              val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV);
+-              val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV);
+-              phy_write(phy, val, RG_PE1_MSTCKDIV_REG);
++              mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
++                             RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
++                             RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV);
+       }
+ }
+@@ -252,13 +240,11 @@ static int mt7621_pci_phy_power_on(struc
+       struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+       u32 offset = (instance->index != 1) ?
+               RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-      u32 val;
+       /* Enable PHY and disable force mode */
+-      val = phy_read(mphy, offset);
+-      val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-      val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-      phy_write(mphy, val, offset);
++      mt7621_phy_rmw(mphy, offset,
++                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
++                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+       return 0;
+ }
+@@ -269,13 +255,11 @@ static int mt7621_pci_phy_power_off(stru
+       struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+       u32 offset = (instance->index != 1) ?
+               RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-      u32 val;
+       /* Disable PHY */
+-      val = phy_read(mphy, offset);
+-      val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-      val |= RG_PE1_FRC_PHY_EN;
+-      phy_write(mphy, val, offset);
++      mt7621_phy_rmw(mphy, offset,
++                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
++                     RG_PE1_FRC_PHY_EN);
+       return 0;
+ }
diff --git a/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch b/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch
new file mode 100644 (file)
index 0000000..393fd4d
--- /dev/null
@@ -0,0 +1,131 @@
+From 3faf4e1c537de86058fc22a851cd979489b9185e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Wed, 18 Mar 2020 10:44:45 +0100
+Subject: [PATCH] staging: mt7621-pci: fix io space and properly set resource
+ limits
+
+Function 'mt7621_pci_parse_request_of_pci_ranges' is using
+'of_pci_range_to_resource' to get both mem and io resources.
+Internally this function calls to 'pci_address_to_pio' which
+returns -1 if io space address is an address > IO_SPACE_LIMIT
+which is 0xFFFF for mips. This mt7621 soc has io space in physical
+address 0x1e160000. In order to fix this, overwrite invalid io
+0xffffffff  with properly values from the device tree and set
+mapped address of this resource as io port base memory address
+calling 'set_io_port_base' function. There is also need to properly
+setup resource limits and io and memory windows with properly
+parsed values instead of set them as 'no limit' which it is wrong.
+For any reason I don't really know legacy driver sets up mem window
+as 0xFFFFFFFF and any other value seems to does not work as expected,
+so set up also here with same values.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200318094445.19669-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 43 +++++++++++++++++++--------------
+ 1 file changed, 25 insertions(+), 18 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -118,6 +118,7 @@ struct mt7621_pcie_port {
+  * @busn: bus range
+  * @offset: IO / Memory offset
+  * @dev: Pointer to PCIe device
++ * @io_map_base: virtual memory base address for io
+  * @ports: pointer to PCIe port information
+  * @resets_inverted: depends on chip revision
+  * reset lines are inverted.
+@@ -132,6 +133,7 @@ struct mt7621_pcie {
+               resource_size_t mem;
+               resource_size_t io;
+       } offset;
++      unsigned long io_map_base;
+       struct list_head ports;
+       bool resets_inverted;
+ };
+@@ -291,22 +293,21 @@ static int mt7621_pci_parse_request_of_p
+       }
+       for_each_of_pci_range(&parser, &range) {
+-              struct resource *res = NULL;
+-
+               switch (range.flags & IORESOURCE_TYPE_BITS) {
+               case IORESOURCE_IO:
+-                      ioremap(range.cpu_addr, range.size);
+-                      res = &pcie->io;
++                      pcie->io_map_base =
++                              (unsigned long)ioremap(range.cpu_addr,
++                                                     range.size);
++                      of_pci_range_to_resource(&range, node, &pcie->io);
++                      pcie->io.start = range.cpu_addr;
++                      pcie->io.end = range.cpu_addr + range.size - 1;
+                       pcie->offset.io = 0x00000000UL;
+                       break;
+               case IORESOURCE_MEM:
+-                      res = &pcie->mem;
++                      of_pci_range_to_resource(&range, node, &pcie->mem);
+                       pcie->offset.mem = 0x00000000UL;
+                       break;
+               }
+-
+-              if (res)
+-                      of_pci_range_to_resource(&range, node, res);
+       }
+       err = of_pci_parse_bus_range(node, &pcie->busn);
+@@ -318,6 +319,8 @@ static int mt7621_pci_parse_request_of_p
+               pcie->busn.flags = IORESOURCE_BUS;
+       }
++      set_io_port_base(pcie->io_map_base);
++
+       return 0;
+ }
+@@ -548,6 +551,10 @@ static void mt7621_pcie_enable_ports(str
+       u32 slot;
+       u32 val;
++      /* Setup MEMWIN and IOWIN */
++      pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE);
++      pcie_write(pcie, pcie->io.start, RALINK_PCI_IOBASE);
++
+       list_for_each_entry(port, &pcie->ports, list) {
+               if (port->enabled) {
+                       mt7621_pcie_port_clk_enable(port);
+@@ -668,11 +675,17 @@ static int mt7621_pci_probe(struct platf
+               return err;
+       }
++      err = mt7621_pci_parse_request_of_pci_ranges(pcie);
++      if (err) {
++              dev_err(dev, "Error requesting pci resources from ranges");
++              goto out_release_gpios;
++      }
++
+       /* set resources limits */
+-      iomem_resource.start = 0;
+-      iomem_resource.end = ~0UL; /* no limit */
+-      ioport_resource.start = 0;
+-      ioport_resource.end = ~0UL; /* no limit */
++      iomem_resource.start = pcie->mem.start;
++      iomem_resource.end = pcie->mem.end;
++      ioport_resource.start = pcie->io.start;
++      ioport_resource.end = pcie->io.end;
+       mt7621_pcie_init_ports(pcie);
+@@ -685,12 +698,6 @@ static int mt7621_pci_probe(struct platf
+       mt7621_pcie_enable_ports(pcie);
+-      err = mt7621_pci_parse_request_of_pci_ranges(pcie);
+-      if (err) {
+-              dev_err(dev, "Error requesting pci resources from ranges");
+-              goto out_release_gpios;
+-      }
+-
+       setup_cm_memory_region(pcie);
+       err = mt7621_pcie_request_resources(pcie, &res);
diff --git a/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch b/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch
new file mode 100644 (file)
index 0000000..5b4c461
--- /dev/null
@@ -0,0 +1,28 @@
+From 0a3085ae142d8f5cf905b104bc66db3721a2fa33 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Thu, 19 Mar 2020 10:57:33 +0100
+Subject: [PATCH] staging: mt7621-pci: fix register to set up virtual bridges
+
+Instead of being using PCI Configuration and Status Register to
+set up virtual bridges we are using CONFIG_ADDR Register which is
+wrong. Hence, set the correct value.
+
+Fixes: 9a5e71a68d20 ("staging: mt7621-pci: simplify 'mt7621_pcie_init_virtual_bridges' function")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200319095733.1557-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -603,7 +603,7 @@ static int mt7621_pcie_init_virtual_brid
+               if ((pcie_link_status & BIT(i)) == 0)
+                       p2p_br_devnum[i] = n++;
+-      pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR,
++      pcie_rmw(pcie, RALINK_PCI_PCICFG_ADDR,
+                PCIE_P2P_BR_DEVNUM_MASK_FULL,
+                (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) |
+                (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
diff --git a/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch b/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch
new file mode 100644 (file)
index 0000000..55abb89
--- /dev/null
@@ -0,0 +1,34 @@
+From 23a788c23ed10e0d79092fcb693dcf0e357e1f7e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Thu, 19 Mar 2020 17:14:16 +0100
+Subject: [PATCH] staging: mt7621-pci: don't return if get gpio fails
+
+In some platforms gpio's are not used for reset but
+for other purposes. Because of that when we try to
+get them are valid gpio's but are already assigned
+to do other function. To avoid those kind of problems
+in those platforms just notice the fail in the kernel
+but continue doing normal boot.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200319161416.19033-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -363,10 +363,8 @@ static int mt7621_pcie_parse_port(struct
+       port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+                                                      GPIOD_OUT_LOW);
+-      if (IS_ERR(port->gpio_rst)) {
+-              dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
+-              return PTR_ERR(port->gpio_rst);
+-      }
++      if (IS_ERR(port->gpio_rst))
++              dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
+       port->slot = slot;
+       port->pcie = pcie;
diff --git a/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch b/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch
new file mode 100644 (file)
index 0000000..6d84bfd
--- /dev/null
@@ -0,0 +1,272 @@
+From 91eb47531421f0e8c9bc4594b4a7caa0e59dc83e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:19 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: avoid to create to different phys
+ for a dual port one
+
+This soc has two phy's for the pcie one of them using just a different
+register for settig it up but sharing all the rest of the config. Until
+now we was presenting this schema as three different phy's in the device
+tree using the 'phy-cells' node property to discriminate an index and
+setting up a complete phy for the dual port index. This sometimes worked
+properly but reconfiguring the same registers twice presents sometimes
+some unstable pcie links and the ports was not properly being detected.
+The problems only appears on hard resets and soft resets was properly
+working. Instead of having this schema just set two phy's in the device
+ree and use the 'phy-cells' property to say if the port has or not a dual
+port. Doing this configuration and set up becomes easier, LOC is decreased
+and the behaviour also gets deterministic with properly and stable pcie
+links in both hard and soft resets.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-2-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 144 ++++++++++--------------
+ 1 file changed, 59 insertions(+), 85 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -78,31 +78,21 @@
+ #define MAX_PHYS      2
+ /**
+- * struct mt7621_pci_phy_instance - Mt7621 Pcie PHY device
+- * @phy: pointer to the kernel PHY device
+- * @port_base: base register
+- * @index: internal ID to identify the Mt7621 PCIe PHY
+- */
+-struct mt7621_pci_phy_instance {
+-      struct phy *phy;
+-      void __iomem *port_base;
+-      u32 index;
+-};
+-
+-/**
+  * struct mt7621_pci_phy - Mt7621 Pcie PHY core
+  * @dev: pointer to device
+  * @regmap: kernel regmap pointer
+- * @phys: pointer to Mt7621 PHY device
+- * @nphys: number of PHY devices for this core
++ * @phy: pointer to the kernel PHY device
++ * @port_base: base register
++ * @has_dual_port: if the phy has dual ports.
+  * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst'
+  * needs to be executed. Depends on chip revision.
+  */
+ struct mt7621_pci_phy {
+       struct device *dev;
+       struct regmap *regmap;
+-      struct mt7621_pci_phy_instance **phys;
+-      int nphys;
++      struct phy *phy;
++      void __iomem *port_base;
++      bool has_dual_port;
+       bool bypass_pipe_rst;
+ };
+@@ -130,23 +120,23 @@ static inline void mt7621_phy_rmw(struct
+       phy_write(phy, val, reg);
+ }
+-static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy,
+-                                 struct mt7621_pci_phy_instance *instance)
++static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy)
+ {
+-      u32 offset = (instance->index != 1) ?
+-              RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH;
++      mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST);
++      mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC);
+-      mt7621_phy_rmw(phy, offset,
+-                     RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC,
+-                     RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
++      if (phy->has_dual_port) {
++              mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
++                             0, RG_PE1_PIPE_RST);
++              mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
++                             0, RG_PE1_PIPE_CMD_FRC);
++      }
+ }
+-static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy,
+-                                 struct mt7621_pci_phy_instance *instance)
++static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
+ {
+       struct device *dev = phy->dev;
+       u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+-      u32 offset;
+       reg = (reg >> 6) & 0x7;
+       /* Set PCIe Port PHY to disable SSC */
+@@ -156,10 +146,13 @@ static void mt7621_set_phy_for_ssc(struc
+                      RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00));
+       /* disable port */
+-      offset = (instance->index != 1) ?
+-              RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-      mt7621_phy_rmw(phy, offset,
+-                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++      mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG,
++                     RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++
++      if (phy->has_dual_port) {
++              mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
++                             RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++      }
+       if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
+               /* Set Pre-divider ratio (for host mode) */
+@@ -223,43 +216,44 @@ static void mt7621_set_phy_for_ssc(struc
+ static int mt7621_pci_phy_init(struct phy *phy)
+ {
+-      struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
+-      struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
++      struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
+       if (mphy->bypass_pipe_rst)
+-              mt7621_bypass_pipe_rst(mphy, instance);
++              mt7621_bypass_pipe_rst(mphy);
+-      mt7621_set_phy_for_ssc(mphy, instance);
++      mt7621_set_phy_for_ssc(mphy);
+       return 0;
+ }
+ static int mt7621_pci_phy_power_on(struct phy *phy)
+ {
+-      struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
+-      struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+-      u32 offset = (instance->index != 1) ?
+-              RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
++      struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
+       /* Enable PHY and disable force mode */
+-      mt7621_phy_rmw(mphy, offset,
+-                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
+-                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
++      mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
++                     RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
++
++      if (mphy->has_dual_port) {
++              mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
++                             RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
++      }
+       return 0;
+ }
+ static int mt7621_pci_phy_power_off(struct phy *phy)
+ {
+-      struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
+-      struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+-      u32 offset = (instance->index != 1) ?
+-              RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
++      struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
+       /* Disable PHY */
+-      mt7621_phy_rmw(mphy, offset,
+-                     RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
+-                     RG_PE1_FRC_PHY_EN);
++      mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
++                     RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++
++      if (mphy->has_dual_port) {
++              mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
++                             RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++      }
+       return 0;
+ }
+@@ -282,13 +276,15 @@ static struct phy *mt7621_pcie_phy_of_xl
+ {
+       struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev);
+-      if (args->args_count == 0)
+-              return mt7621_phy->phys[0]->phy;
+-
+       if (WARN_ON(args->args[0] >= MAX_PHYS))
+               return ERR_PTR(-ENODEV);
+-      return mt7621_phy->phys[args->args[0]]->phy;
++      mt7621_phy->has_dual_port = args->args[0];
++
++      dev_info(dev, "PHY for 0x%08x (dual port = %d)\n",
++               (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port);
++
++      return mt7621_phy->phy;
+ }
+ static const struct soc_device_attribute mt7621_pci_quirks_match[] = {
+@@ -309,19 +305,11 @@ static int mt7621_pci_phy_probe(struct p
+       struct phy_provider *provider;
+       struct mt7621_pci_phy *phy;
+       struct resource *res;
+-      int port;
+-      void __iomem *port_base;
+       phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy)
+               return -ENOMEM;
+-      phy->nphys = MAX_PHYS;
+-      phy->phys = devm_kcalloc(dev, phy->nphys,
+-                               sizeof(*phy->phys), GFP_KERNEL);
+-      if (!phy->phys)
+-              return -ENOMEM;
+-
+       attr = soc_device_match(mt7621_pci_quirks_match);
+       if (attr)
+               phy->bypass_pipe_rst = true;
+@@ -335,39 +323,25 @@ static int mt7621_pci_phy_probe(struct p
+               return -ENXIO;
+       }
+-      port_base = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(port_base)) {
++      phy->port_base = devm_ioremap_resource(dev, res);
++      if (IS_ERR(phy->port_base)) {
+               dev_err(dev, "failed to remap phy regs\n");
+-              return PTR_ERR(port_base);
++              return PTR_ERR(phy->port_base);
+       }
+-      phy->regmap = devm_regmap_init_mmio(phy->dev, port_base,
++      phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base,
+                                           &mt7621_pci_phy_regmap_config);
+       if (IS_ERR(phy->regmap))
+               return PTR_ERR(phy->regmap);
+-      for (port = 0; port < MAX_PHYS; port++) {
+-              struct mt7621_pci_phy_instance *instance;
+-              struct phy *pphy;
+-
+-              instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
+-              if (!instance)
+-                      return -ENOMEM;
+-
+-              phy->phys[port] = instance;
+-
+-              pphy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
+-              if (IS_ERR(phy)) {
+-                      dev_err(dev, "failed to create phy\n");
+-                      return PTR_ERR(phy);
+-              }
+-
+-              instance->port_base = port_base;
+-              instance->phy = pphy;
+-              instance->index = port;
+-              phy_set_drvdata(pphy, instance);
++      phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
++      if (IS_ERR(phy)) {
++              dev_err(dev, "failed to create phy\n");
++              return PTR_ERR(phy);
+       }
++      phy_set_drvdata(phy->phy, phy);
++
+       provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate);
+       return PTR_ERR_OR_ZERO(provider);
diff --git a/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch b/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch
new file mode 100644 (file)
index 0000000..61aa80e
--- /dev/null
@@ -0,0 +1,42 @@
+From c752b54bda4d772426c5eeb56978d2e41bd525b4 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:21 +0100
+Subject: [PATCH] staging: mt7621-pci: use only two phys from device tree
+
+In order to align work with the mt7621-pci-phy part of
+the driver and device tree which is now using only two
+real phys one of them dual ported properly parse the
+device tree and don't call phy initialization for the
+slot 1 because is being taking into account when the
+phy for the slot 0 is instantiated.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-4-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -358,7 +358,7 @@ static int mt7621_pcie_parse_port(struct
+       snprintf(name, sizeof(name), "pcie-phy%d", slot);
+       port->phy = devm_phy_get(dev, name);
+-      if (IS_ERR(port->phy))
++      if (IS_ERR(port->phy) && slot != 1)
+               return PTR_ERR(port->phy);
+       port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+@@ -495,6 +495,11 @@ static void mt7621_pcie_init_ports(struc
+       list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+               u32 slot = port->slot;
++              if (slot == 1) {
++                      port->enabled = true;
++                      continue;
++              }
++
+               err = mt7621_pcie_init_port(port);
+               if (err) {
+                       dev_err(dev, "Initiating port %d failed\n", slot);
diff --git a/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch b/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch
new file mode 100644 (file)
index 0000000..383c896
--- /dev/null
@@ -0,0 +1,26 @@
+From b59343b7de448c30e5b098484a7c7c5cb300df2f Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:22 +0100
+Subject: [PATCH] staging: mt7621-pci: change variable to print for slot
+
+We are using the counter to print the slot which has been
+enabled. Use the correct associated slot for the port instead.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-5-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -562,7 +562,7 @@ static void mt7621_pcie_enable_ports(str
+               if (port->enabled) {
+                       mt7621_pcie_port_clk_enable(port);
+                       mt7621_pcie_enable_port(port);
+-                      dev_info(dev, "PCIE%d enabled\n", num_slots_enabled);
++                      dev_info(dev, "PCIE%d enabled\n", port->slot);
+                       num_slots_enabled++;
+               }
+       }
diff --git a/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch b/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch
new file mode 100644 (file)
index 0000000..bf6fdf1
--- /dev/null
@@ -0,0 +1,33 @@
+From 87068309300c707d659ce79232eae827604804a4 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:23 +0100
+Subject: [PATCH] staging: mt7621-pci: be sure gpio descriptor is null on fails
+
+Function 'devm_gpiod_get_index_optional' returns NULL if the
+descriptor is invalid and the error associated for the error
+pointer is ENOENT. Sometimes if the pin is just assigned the
+error associated for the pointer might not be ENOENT but other.
+In order to avoid weirds behaviours if this happen set descriptor
+to NULL in the driver port structure.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-6-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -363,8 +363,10 @@ static int mt7621_pcie_parse_port(struct
+       port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+                                                      GPIOD_OUT_LOW);
+-      if (IS_ERR(port->gpio_rst))
++      if (IS_ERR(port->gpio_rst)) {
+               dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
++              port->gpio_rst = NULL;
++      }
+       port->slot = slot;
+       port->pcie = pcie;
diff --git a/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch b/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch
new file mode 100644 (file)
index 0000000..d733e58
--- /dev/null
@@ -0,0 +1,79 @@
+From d81fe3c13aa6f4ab1ec318212d2007175e6d05aa Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 16:38:37 +0100
+Subject: [PATCH] staging: mt7621-pci: avoid to poweroff the phy for slot one
+
+Phy for slot 0 and 1 is shared and handled properly in slot 0.
+If there is only one port in use,(slot 0) we shall not call the
+'phy_power_off' function with an invalid slot because kernel
+will crash with an unaligned access fault like the following:
+
+mt7621-pci 1e140000.pcie: Error applying setting, reverse things back
+mt7621-pci-phy 1e149000.pcie-phy: PHY for 0xbe149000 (dual port = 1)
+mt7621-pci-phy 1e14a000.pcie-phy: PHY for 0xbe14a000 (dual port = 0)
+mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
+mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz
+mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK)
+Unhandled kernel unaligned access[#1]:
+CPU: 3 PID: 111 Comm: kworker/3:2 Not tainted 5.6.0-rc3-00347-g825c6f470c62-dirty #9
+Workqueue: events deferred_probe_work_func
+$ 0   : 00000000 00000001 5f60d043 8fe1ba80
+$ 4   : 0000010d 01eb9000 00000000 00000000
+$ 8   : 294b4c00 80940000 00000008 000000ce
+$12   : 2e303030 00000000 00000000 65696370
+$16   : ffffffed 0000010d 8e373cd0 8214c1e0
+$20   : 00000000 82144c80 82144680 8214c250
+$24   : 00000018 803ef8f4
+$28   : 8e372000 8e373c60 8214c080 803940e8
+Hi    : 00000125
+Lo    : 122f2000
+epc   : 807b3328 mutex_lock+0x8/0x44
+ra    : 803940e8 phy_power_off+0x28/0xb0
+Status: 1100fc03        KERNEL EXL IE
+Cause : 00800010 (ExcCode 04)
+BadVA : 0000010d
+PrId  : 0001992f (MIPS 1004Kc)
+Modules linked in:
+Process kworker/3:2 (pid: 111, threadinfo=(ptrval), task=(ptrval), tls=00000000)
+Stack : 8e373cd0 803fe4f4 8e372000 8e373c90 8214c080 804fde1c 8e373c98 808d62f4
+         8e373c78 00000000 8214c254 804fe648 1e160000 804f27b8 00000001 808d62f4
+         00000000 00000001 8214c228 808d62f4 80930000 809a0000 8fd47e10 808d63d4
+         808d62d4 8fd47e10 808d0000 808d0000 8e373cd0 8e373cd0 809e2a74 809db510
+         809db510 00000006 00000001 00000000 00000000 00000000 01000000 1e1440ff
+         ...
+Call Trace:
+[<807b3328>] mutex_lock+0x8/0x44
+[<803940e8>] phy_power_off+0x28/0xb0
+[<804fe648>] mt7621_pci_probe+0xc20/0xd18
+[<80402ab8>] platform_drv_probe+0x40/0x94
+[<80400a74>] really_probe+0x104/0x364
+[<803feb74>] bus_for_each_drv+0x84/0xdc
+[<80400924>] __device_attach+0xdc/0x120
+[<803ffb5c>] bus_probe_device+0xa0/0xbc
+[<80400124>] deferred_probe_work_func+0x7c/0xbc
+[<800420e8>] process_one_work+0x230/0x450
+[<80042638>] worker_thread+0x330/0x5fc
+[<80048eb0>] kthread+0x12c/0x134
+[<80007438>] ret_from_kernel_thread+0x14/0x1c
+Code: 24050002  27bdfff8  8f830000 <c0850000> 14a00005  00000000  00600825  e0810000  1020fffa
+
+Fixes: bf516f413f4e ("staging: mt7621-pci: use only two phys from device tree")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320153837.20415-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -517,7 +517,8 @@ static void mt7621_pcie_init_ports(struc
+               if (!mt7621_pcie_port_is_linkup(port)) {
+                       dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
+                               slot);
+-                      phy_power_off(port->phy);
++                      if (slot != 1)
++                              phy_power_off(port->phy);
+                       mt7621_control_assert(port);
+                       mt7621_pcie_port_clk_disable(port);
+                       port->enabled = false;
diff --git a/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch b/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch
new file mode 100644 (file)
index 0000000..5bfd205
--- /dev/null
@@ -0,0 +1,91 @@
+From 9d789a7728c37e8730b6a9cca60cf155f18537ea Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 08:26:50 +0100
+Subject: [PATCH] staging: mt7621-pci: delete release gpios related code
+
+Making gpio8 and gpio9 vendor specific and putting them
+into the specific dts file makes not needed to release
+gpios anymore because we are not occupying those pins
+in the first place if it is not necessary. When the
+device tree is parsed we can also check and return for
+the error because we rely in the fact that the related
+device for the board is correct.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321072650.7784-3-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 27 +++++++--------------------
+ 1 file changed, 7 insertions(+), 20 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -364,8 +364,8 @@ static int mt7621_pcie_parse_port(struct
+       port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+                                                      GPIOD_OUT_LOW);
+       if (IS_ERR(port->gpio_rst)) {
+-              dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
+-              port->gpio_rst = NULL;
++              dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
++              return PTR_ERR(port->gpio_rst);
+       }
+       port->slot = slot;
+@@ -474,15 +474,6 @@ static void mt7621_pcie_reset_ep_deasser
+       mdelay(PERST_DELAY_MS);
+ }
+-static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie)
+-{
+-      struct mt7621_pcie_port *port;
+-
+-      list_for_each_entry(port, &pcie->ports, list)
+-              if (port->gpio_rst)
+-                      gpiod_put(port->gpio_rst);
+-}
+-
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
+ {
+       struct device *dev = pcie->dev;
+@@ -684,7 +675,7 @@ static int mt7621_pci_probe(struct platf
+       err = mt7621_pci_parse_request_of_pci_ranges(pcie);
+       if (err) {
+               dev_err(dev, "Error requesting pci resources from ranges");
+-              goto out_release_gpios;
++              return err;
+       }
+       /* set resources limits */
+@@ -698,8 +689,7 @@ static int mt7621_pci_probe(struct platf
+       err = mt7621_pcie_init_virtual_bridges(pcie);
+       if (err) {
+               dev_err(dev, "Nothing is connected in virtual bridges. Exiting...");
+-              err = 0;
+-              goto out_release_gpios;
++              return 0;
+       }
+       mt7621_pcie_enable_ports(pcie);
+@@ -709,19 +699,16 @@ static int mt7621_pci_probe(struct platf
+       err = mt7621_pcie_request_resources(pcie, &res);
+       if (err) {
+               dev_err(dev, "Error requesting resources\n");
+-              goto out_release_gpios;
++              return err;
+       }
+       err = mt7621_pcie_register_host(bridge, &res);
+       if (err) {
+               dev_err(dev, "Error registering host\n");
+-              goto out_release_gpios;
++              return err;
+       }
+-out_release_gpios:
+-      mt7621_pcie_release_gpios(pcie);
+-
+-      return err;
++      return 0;
+ }
+ static const struct of_device_id mt7621_pci_ids[] = {
diff --git a/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch b/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch
new file mode 100644 (file)
index 0000000..b333bb3
--- /dev/null
@@ -0,0 +1,29 @@
+From 60a15339ceab9fc2a6cdc85fd54b66b2c947ab4e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 14:36:21 +0100
+Subject: [PATCH] staging: mt7621-pci: use builtin_platform_driver()
+
+Macro builtin_platform_driver can be used for builtin drivers
+that don't do anything in driver init. So, use the macro
+builtin_platform_driver and remove some boilerplate code.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321133624.31388-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -725,9 +725,4 @@ static struct platform_driver mt7621_pci
+       },
+ };
+-static int __init mt7621_pci_init(void)
+-{
+-      return platform_driver_register(&mt7621_pci_driver);
+-}
+-
+-module_init(mt7621_pci_init);
++builtin_platform_driver(mt7621_pci_driver);
diff --git a/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch b/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch
new file mode 100644 (file)
index 0000000..e55def4
--- /dev/null
@@ -0,0 +1,32 @@
+From ffe3dee4081055b4f58bc50dd3f5c97de42cf126 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 14:36:23 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: use builtin_platform_driver()
+
+Macro builtin_platform_driver can be used for builtin drivers
+that don't do anything in driver init. So, use the macro
+builtin_platform_driver and remove some boilerplate code.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321133624.31388-3-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -361,12 +361,7 @@ static struct platform_driver mt7621_pci
+       },
+ };
+-static int __init mt7621_pci_phy_drv_init(void)
+-{
+-      return platform_driver_register(&mt7621_pci_phy_driver);
+-}
+-
+-module_init(mt7621_pci_phy_drv_init);
++builtin_platform_driver(mt7621_pci_phy_driver);
+ MODULE_AUTHOR("Sergio Paracuellos <sergio.paracuellos@gmail.com>");
+ MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver");
diff --git a/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch b/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch
new file mode 100644 (file)
index 0000000..9eb8345
--- /dev/null
@@ -0,0 +1,68 @@
+From ff83e3023cb8fc3b5dfc12e0c91bf1eb9dc4c4c6 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 14:36:24 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: re-do 'xtal_mode' detection
+
+Detection of the Xtal mode is using magic numbers that
+can be avoided using properly some definitions and a more
+accurate variable name from 'reg' into 'xtal_mode'. This
+increase readability.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321133624.31388-4-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -75,6 +75,9 @@
+ #define RG_PE1_FRC_MSTCKDIV                   BIT(5)
++#define XTAL_MODE_SEL_SHIFT                   6
++#define XTAL_MODE_SEL_MASK                    0x7
++
+ #define MAX_PHYS      2
+ /**
+@@ -136,9 +139,11 @@ static void mt7621_bypass_pipe_rst(struc
+ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
+ {
+       struct device *dev = phy->dev;
+-      u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
++      u32 xtal_mode;
++
++      xtal_mode = (rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0)
++                   >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
+-      reg = (reg >> 6) & 0x7;
+       /* Set PCIe Port PHY to disable SSC */
+       /* Debug Xtal Type */
+       mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
+@@ -154,13 +159,13 @@ static void mt7621_set_phy_for_ssc(struc
+                              RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
+       }
+-      if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
++      if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
+               /* Set Pre-divider ratio (for host mode) */
+               mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
+                              RG_PE1_H_PLL_PREDIV,
+                              RG_PE1_H_PLL_PREDIV_VAL(0x01));
+               dev_info(dev, "Xtal is 40MHz\n");
+-      } else if (reg >= 6) { /* 25MHz Xal */
++      } else if (xtal_mode >= 6) { /* 25MHz Xal */
+               mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
+                              RG_PE1_H_PLL_PREDIV,
+                              RG_PE1_H_PLL_PREDIV_VAL(0x00));
+@@ -206,7 +211,7 @@ static void mt7621_set_phy_for_ssc(struc
+       mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG,
+                      RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00));
+-      if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
++      if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
+               /* set force mode enable of da_pe1_mstckdiv */
+               mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
+                              RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
diff --git a/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch b/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch
new file mode 100644 (file)
index 0000000..9af46f4
--- /dev/null
@@ -0,0 +1,35 @@
+From 4f0f36b67564311a4ce4441510ef94848febbab2 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sun, 22 Mar 2020 08:21:28 +0100
+Subject: [PATCH] staging: mt7621-pci: avoid to set 'iomem_resource' addresses
+
+Setting up kernel resource 'iomem_resource' for PCI with
+addresses parsed from device tree gots into a conflict within
+the usb xhci driver:
+
+xhci-mtk 1e1c0000.xhci: can't request region for resource [mem 0x1e1c0000-0x1e1c0fff]
+xhci-mtk: probe of 1e1c0000.xhci failed with error -16
+
+Don't assign it and maintain the default addresses for this
+resource seems to fix the problem. Checking legacy driver it
+is being only  setting the 'ioport_resource'.
+
+Fixes: 09dd629eeabb ("staging: mt7621-pci: fix io space and properly set resource limits")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200322072128.4454-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -679,8 +679,6 @@ static int mt7621_pci_probe(struct platf
+       }
+       /* set resources limits */
+-      iomem_resource.start = pcie->mem.start;
+-      iomem_resource.end = pcie->mem.end;
+       ioport_resource.start = pcie->io.start;
+       ioport_resource.end = pcie->io.end;