From: DENG Qingfang Date: Wed, 11 Mar 2020 13:05:41 +0000 (+0800) Subject: ramips: mt7621: backport PCIe driver fixes from staging-test X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=d21d6ea4547412632e01de505b7a2c8a83817a02;p=openwrt%2Fstaging%2Fjow.git ramips: mt7621: backport PCIe driver fixes from staging-test Backport mt7621-pci/mt7621-pci-phy fixes from staging-test Signed-off-by: DENG Qingfang --- 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 index 0000000000..b9bcd63488 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch @@ -0,0 +1,133 @@ +From b327cd58c3fec1c6382128e929eab9bc0d68e912 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200308091928.17177-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..3939280a16 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch @@ -0,0 +1,74 @@ +From 550fabd71d7fcdfe099bbf41e00e28719737161e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200310113459.30539-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..1b7828f1e6 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch @@ -0,0 +1,222 @@ +From 227a8bf421ff8b085444e51e471ef06a87228cfd Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200313200913.24321-2-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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, ®s); + 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 index 0000000000..3d86355b29 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch @@ -0,0 +1,45 @@ +From e462e7d3211479df42357a620fa788a2257556b7 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200313200913.24321-3-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..f24bf833c9 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch @@ -0,0 +1,76 @@ +From 4d6a758f2cd2122a7d895f913854c13da62ba6df Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200313200913.24321-6-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..fc509e945b --- /dev/null +++ b/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch @@ -0,0 +1,46 @@ +From 4be54c3a495f08c05a8e485566e5b88cd3537f16 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200313200913.24321-7-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..234af32308 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch @@ -0,0 +1,234 @@ +From bf0c6782e5b9a6deee4e223655325dc004fae8dd Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200315160154.10292-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..393fd4d5dd --- /dev/null +++ b/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch @@ -0,0 +1,131 @@ +From 3faf4e1c537de86058fc22a851cd979489b9185e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200318094445.19669-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..5b4c461b2f --- /dev/null +++ b/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch @@ -0,0 +1,28 @@ +From 0a3085ae142d8f5cf905b104bc66db3721a2fa33 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200319095733.1557-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..55abb8999f --- /dev/null +++ b/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch @@ -0,0 +1,34 @@ +From 23a788c23ed10e0d79092fcb693dcf0e357e1f7e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200319161416.19033-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..6d84bfdd5b --- /dev/null +++ b/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch @@ -0,0 +1,272 @@ +From 91eb47531421f0e8c9bc4594b4a7caa0e59dc83e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200320110123.9907-2-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..61aa80eb76 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch @@ -0,0 +1,42 @@ +From c752b54bda4d772426c5eeb56978d2e41bd525b4 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200320110123.9907-4-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..383c896a3e --- /dev/null +++ b/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch @@ -0,0 +1,26 @@ +From b59343b7de448c30e5b098484a7c7c5cb300df2f Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200320110123.9907-5-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..bf6fdf1d49 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch @@ -0,0 +1,33 @@ +From 87068309300c707d659ce79232eae827604804a4 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200320110123.9907-6-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..d733e58537 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch @@ -0,0 +1,79 @@ +From d81fe3c13aa6f4ab1ec318212d2007175e6d05aa Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 14a00005 00000000 00600825 e0810000 1020fffa + +Fixes: bf516f413f4e ("staging: mt7621-pci: use only two phys from device tree") +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20200320153837.20415-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..5bfd205691 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch @@ -0,0 +1,91 @@ +From 9d789a7728c37e8730b6a9cca60cf155f18537ea Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200321072650.7784-3-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..b333bb326b --- /dev/null +++ b/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch @@ -0,0 +1,29 @@ +From 60a15339ceab9fc2a6cdc85fd54b66b2c947ab4e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200321133624.31388-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..e55def40f5 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch @@ -0,0 +1,32 @@ +From ffe3dee4081055b4f58bc50dd3f5c97de42cf126 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200321133624.31388-3-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 "); + 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 index 0000000000..9eb8345144 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch @@ -0,0 +1,68 @@ +From ff83e3023cb8fc3b5dfc12e0c91bf1eb9dc4c4c6 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200321133624.31388-4-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..9af46f4196 --- /dev/null +++ b/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch @@ -0,0 +1,35 @@ +From 4f0f36b67564311a4ce4441510ef94848febbab2 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +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 +Link: https://lore.kernel.org/r/20200322072128.4454-1-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + 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; +