Re: staging: mt7621-pci: factor out 'mt7621_pcie_enable_port' function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Greg,

On Thu, May 30, 2019 at 3:46 AM Greg Ungerer <gerg@xxxxxxxxxx> wrote:
>
> Hi Sergio,
>
> On 30/5/19 10:44 am, Greg Ungerer wrote:
> > On 29/5/19 6:08 pm, Sergio Paracuellos wrote:
> > [snip]
> >> I have added gpio consumer stuff and reorder a bit the code to be more
> >> similar to 4.20.
> >>
> >> I attach the patch. I have not try it to compile it, because my normal
> >> environment is in another
> >> computer and I am in the middle of moving from my current house and
> >> don't have access to it, sorry.
> >> So, please try this and let's see what happens.
> >
> > No problem, thanks for the patch.
> >
> > Unfortunately always locks up on kernel boot:
> >
> >    ...
> >    mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
> >    mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 0
> >    mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
> >    mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 1
> >    mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz
> >    mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 2
> >    mt7621-pci 1e140000.pcie: pcie0 no card, disable it (RST & CLK)
> >    mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK)
> >    mt7621-pci 1e140000.pcie: pcie2 no card, disable it (RST & CLK)
> >
> > That was original linux-5.1 patched with your attached patch.
> >
> > I'll try and dig down into that further today and get some
> > feedback on where it is failing.
>
> The first problem I see is that the GPIO MODE register bits for
> PERST_MODE are set to 00, so in "PCIe Reset" mode. If I hack in
> a register update for that with:
>
>      /* Force PERST PCIe reset into GPIO mode */
>      *(unsigned int *)(0xbe000060) |=  BIT(10);

I have set GPIO mode for this in the new attached patch.

>
> I do that at the start of mt7621_pcie_init_ports(). With that in
> place I get further:
>
>    mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
>    mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 0
>    mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
>    mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 1
>    mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz
>    mt7621-pci 1e140000.pcie: Port 454043648 N_FTS = 2
>    mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK)
>    mt7621-pci 1e140000.pcie: pcie2 no card, disable it (RST & CLK)
>    mt7621-pci 1e140000.pcie: PCIE0 enabled
>    mt7621-pci 1e140000.pcie: PCI coherence region base: 0x60000000, mask/settings: 0xf0000002
>    mt7621-pci 1e140000.pcie: PCI host bridge to bus 0000:00
>    pci_bus 0000:00: root bus resource [io  0xffffffff]
>    pci_bus 0000:00: root bus resource [mem 0x60000000-0x6fffffff]
>    pci_bus 0000:00: root bus resource [bus 00-ff]
>    pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
>
> It hangs there...

I had review the boot order is working for you in version 4.20 and the
order with the new patch applied. There were
only one difference, the place where interrupt bits are set. I have
changed that also in the new attached patch.

For me, the order now and how the different boot steps are being done
in v4.20 are the same.

One other thing I don't really understand why is needed but is in the
v4.20 code are this two lines:

pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE);
pcie_write(pcie, RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);

These are added also in the current patch.

>
> Regards
> Greg

Hope this helps.

Best regards,
    Sergio Paracuellos
>
>
From be6e894e4592ac0ad7edca590ebff8f5e80a9733 Mon Sep 17 00:00:00 2001
From: Sergio Paracuellos <sergio.paracuellos@xxxxxxxxx>
Date: Wed, 29 May 2019 09:58:07 +0200
Subject: [PATCH] staging: mt7621-pci: use perst gpio instead of builtin perst

Some boards need gpio instead of builtin perst. Use gpio for all
of them which was the approach of the original code.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@xxxxxxxxx>
---
 drivers/staging/mt7621-dts/mt7621.dtsi  |   3 +-
 drivers/staging/mt7621-pci/pci-mt7621.c | 113 +++++++++++++++++---------------
 2 files changed, 61 insertions(+), 55 deletions(-)

diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
index 280ec33..aed2458 100644
--- a/drivers/staging/mt7621-dts/mt7621.dtsi
+++ b/drivers/staging/mt7621-dts/mt7621.dtsi
@@ -1,5 +1,5 @@
 #include <dt-bindings/interrupt-controller/mips-gic.h>
-
+#include <dt-bindings/gpio/gpio.h>
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
@@ -468,6 +468,7 @@
 		#address-cells = <3>;
 		#size-cells = <2>;
 
+		perst-gpio = <&gpio 19 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pcie_pins>;
 
diff --git a/drivers/staging/mt7621-pci/pci-mt7621.c b/drivers/staging/mt7621-pci/pci-mt7621.c
index 03d919a..25970f5 100644
--- a/drivers/staging/mt7621-pci/pci-mt7621.c
+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
@@ -17,6 +17,7 @@
 
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -35,6 +36,7 @@
 
 /* sysctl */
 #define MT7621_CHIP_REV_ID		0x0c
+#define MT7621_GPIO_MODE        0x60
 #define CHIP_REV_MT7621_E2		0x0101
 
 /* MediaTek specific configuration registers */
@@ -75,13 +77,13 @@
 #define RALINK_PCI_STATUS		0x0050
 
 /* Some definition values */
+#define RALINK_PCI_IO_MAP_BASE  0x1e160000
 #define PCIE_REVISION_ID		BIT(0)
 #define PCIE_CLASS_CODE			(0x60400 << 8)
 #define PCIE_BAR_MAP_MAX		GENMASK(30, 16)
 #define PCIE_BAR_ENABLE			BIT(0)
 #define PCIE_PORT_INT_EN(x)		BIT(20 + (x))
 #define PCIE_PORT_CLK_EN(x)		BIT(24 + (x))
-#define PCIE_PORT_PERST(x)		BIT(1 + (x))
 #define PCIE_PORT_LINKUP		BIT(0)
 
 #define PCIE_CLK_GEN_EN			BIT(31)
@@ -90,6 +92,9 @@
 #define PCIE_CLK_GEN1_EN		(BIT(27) | BIT(25))
 #define MEMORY_BASE			0x0
 
+#define PERST_MODE_GPIO         BIT(10)
+#define PERST_DELAY_US          1000
+
 /**
  * struct mt7621_pcie_port - PCIe port information
  * @base: I/O mapped register base
@@ -119,6 +124,7 @@ 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
  */
 struct mt7621_pcie {
@@ -132,6 +138,7 @@ struct mt7621_pcie {
 		resource_size_t io;
 	} offset;
 	struct list_head ports;
+    struct gpio_desc *perst;
 	struct reset_control *rst;
 };
 
@@ -198,6 +205,18 @@ static void write_config(struct mt7621_pcie *pcie, unsigned int dev,
 	pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA);
 }
 
+static void mt7621_perst_gpio_pcie_assert(struct mt7621_pcie *pcie)
+{
+    gpiod_set_value(pcie->perst, 0);
+    mdelay(PERST_DELAY_US);
+}
+
+static void mt7621_perst_gpio_pcie_deassert(struct mt7621_pcie *pcie)
+{
+    gpiod_set_value(pcie->perst, 1);
+    mdelay(PERST_DELAY_US);
+}
+
 static inline void mt7621_control_assert(struct mt7621_pcie_port *port)
 {
 	u32 chip_rev_id = rt_sysc_r32(MT7621_CHIP_REV_ID);
@@ -344,6 +363,12 @@ static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie)
 	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");
@@ -384,7 +409,6 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port)
 	struct mt7621_pcie *pcie = port->pcie;
 	struct device *dev = pcie->dev;
 	u32 slot = port->slot;
-	u32 val = 0;
 	int err;
 
 	/*
@@ -393,47 +417,33 @@ static int mt7621_pcie_init_port(struct mt7621_pcie_port *port)
 	 */
 	mt7621_reset_port(port);
 
-	val = read_config(pcie, slot, PCIE_FTS_NUM);
-	dev_info(dev, "Port %d N_FTS = %x\n", (unsigned int)val, slot);
-
 	err = phy_init(port->phy);
 	if (err) {
 		dev_err(dev, "failed to initialize port%d phy\n", slot);
-		goto err_phy_init;
+		return err;
 	}
 
 	err = phy_power_on(port->phy);
 	if (err) {
 		dev_err(dev, "failed to power on port%d phy\n", slot);
-		goto err_phy_on;
-	}
-
-	if ((pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) == 0) {
-		dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", slot);
-		mt7621_control_assert(port);
-		port->enabled = false;
-		err = -ENODEV;
-		goto err_no_link_up;
+		return err;
 	}
 
 	port->enabled = true;
 
 	return 0;
-
-err_no_link_up:
-	phy_power_off(port->phy);
-err_phy_on:
-	phy_exit(port->phy);
-err_phy_init:
-	return err;
 }
 
 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_w32(PERST_MODE_GPIO, MT7621_GPIO_MODE);
+    mt7621_perst_gpio_pcie_assert(pcie);
+
 	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
 		u32 slot = port->slot;
 
@@ -441,7 +451,10 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
 		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", (unsigned int)val, slot);
+        }
 	}
 
 	reset_control_assert(pcie->rst);
@@ -451,37 +464,32 @@ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
 	rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN);
 	msleep(50);
 	reset_control_deassert(pcie->rst);
+
+    mt7621_perst_gpio_pcie_deassert(pcie);
+
+	list_for_each_entry(port, &pcie->ports, list) {
+		u32 slot = port->slot;
+
+	    if ((pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) == 0) {
+		    dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", slot);
+		    mt7621_control_assert(port);
+            phy_power_off(port->phy);
+		    port->enabled = false;
+        } else {
+	        /* enable pcie interrupt */
+	        val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR);
+	        val |= PCIE_PORT_INT_EN(slot);
+	        pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR);
+        }
+	}
 }
 
-static int mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
+static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
 {
 	struct mt7621_pcie *pcie = port->pcie;
 	u32 slot = port->slot;
 	u32 offset = MT7621_PCIE_OFFSET + (slot * MT7621_NEXT_PORT);
 	u32 val;
-	int err;
-
-	/* assert port PERST_N */
-	val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
-	val |= PCIE_PORT_PERST(slot);
-	pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
-
-	/* de-assert port PERST_N */
-	val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
-	val &= ~PCIE_PORT_PERST(slot);
-	pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
-
-	/* 100ms timeout value should be enough for Gen1 training */
-	err = readl_poll_timeout(port->base + RALINK_PCI_STATUS,
-				 val, !!(val & PCIE_PORT_LINKUP),
-				 20, 100 * USEC_PER_MSEC);
-	if (err)
-		return -ETIMEDOUT;
-
-	/* enable pcie interrupt */
-	val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR);
-	val |= PCIE_PORT_INT_EN(slot);
-	pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR);
 
 	/* map 2G DDR region */
 	pcie_write(pcie, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE,
@@ -492,8 +500,6 @@ static int mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
 	/* configure class code and revision ID */
 	pcie_write(pcie, PCIE_CLASS_CODE | PCIE_REVISION_ID,
 		   offset + RALINK_PCI_CLASS);
-
-	return 0;
 }
 
 static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie)
@@ -506,11 +512,7 @@ static void mt7621_pcie_enable_ports(struct mt7621_pcie *pcie)
 
 	list_for_each_entry(port, &pcie->ports, list) {
 		if (port->enabled) {
-			if (mt7621_pcie_enable_port(port)) {
-				dev_err(dev, "de-assert port %d PERST_N\n",
-					port->slot);
-				continue;
-			}
+			mt7621_pcie_enable_port(port);
 			dev_info(dev, "PCIE%d enabled\n", slot);
 			num_slots_enabled++;
 		}
@@ -665,6 +667,9 @@ static int mt7621_pci_probe(struct platform_device *pdev)
 		return 0;
 	}
 
+    pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE);
+    pcie_write(pcie, RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);
+
 	mt7621_pcie_enable_ports(pcie);
 
 	err = mt7621_pci_parse_request_of_pci_ranges(pcie);
-- 
2.7.4

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux