[BPI-R3] NVME connection issue

Indeed, a nvme quirk, but that only works after pcie is up.

Have not seen any log to see what fails.

I think a nvme quirk won’t work in this case, because lspci is not even showing nvme. After comparing logs on cold boot against warm boot log, this is what is is cold boot log:

mtk-pcie-gen3 11290000.pcie: PCIe link down, current LTSSM state: recovery.equalization (0xc03c017) mtk-pcie-gen3 11290000.pcie: probe with driver mtk-pcie-gen3 failed with error -110

In warm boot those lines are not present and in exchange shows a lot of lines of nvme initialization

have you looked for the r4 i2c pins or a v1.2 R4? but that should not cause a working/non-working behaviour

If i understand you right, i’m not taping ssd pins, because my board has not anymore R228 and R230 on it.

The weird thing is only on reboot works fine.

Yes i guess your ssd just need a bit more time (which is already passed on warm reboot),so maybe a quirk with bootup delay may help.

Would you please tell me how can this get done to try?

Thank you!

Somethng like this,but with your pci ids

https://lkml.org/lkml/2016/8/15/21

Ok, i’ll check it after work. Will share with you after trying that.

Thank you.

It fails before it can get the pci vendor/product codes. It needs some fix for PCIe initialisation

Hi, Eric.

Is there an example you could provide to see how to do that please? I’ve been reading on many threads and still clueless.

Thank you.

There was some PCIe patch with 100ms delay with PERST line.

Not sure if that still applies to the mtk PCIe, nor if it will help with your pcie device.

I’d tried that last weekend, and did not worked, compiled a second one with 200 ms and still failing.

The process take some time to compile, and that’s why i just tried 2 times.

Later i’ll show you that patch

This is the second patch with wich made my last compilation:

611-pcie-mediatek-gen3-PERST-for-100ms.patch (681 Bytes)

It is based on this: https://forum.banana-pi.org/t/bpi-r3-nvme-connection-issue/14563/17?u=sunchar, i just increased time and updated for kernel 6.18

Not sure why, the 611 patch was deleted from OpenWrt in April (commit 2129465f980c8). I also need it for my NVME, so I readded it to my local tree a few months ago. EDIT: for me 100ms is enough.

Don’t know why is not enough with 200 ms, i was thinking that the patch was wrong. Which model is your SSD? When it is not detected logs the same as with mine?

mtk-pcie-gen3 11290000.pcie: PCIe link down, current LTSSM state: recovery.equalization (0xc03c017) mtk-pcie-gen3 11290000.pcie: probe with driver mtk-pcie-gen3 failed with error -110

Had the same dmesg errors as you, see discussion here:

My SSD is INTEL MEMPEK1J016GAL (M10 16GB).

BTW, my version of 611 is a bit different than yours:

$ cat target/linux/mediatek/patches-6.18/611-pcie-mediatek-gen3-PERST-for-100ms.patch
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -487,8 +487,13 @@ static int mtk_pcie_startup_port(struct
                msleep(PCIE_T_PVPERL_MS);

                /* De-assert reset signals */
-               val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
-                        PCIE_PE_RSTB);
+               val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB);
+               writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
+
+               msleep(PCIE_T_PVPERL_MS);
+
+               /* De-assert PERST# signal */
+               val &= ~(PCIE_PE_RSTB);
                writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);

Hi raenye.

Yes, it looks a little different. I had to edit again pcie-mediatek-gen3.c file, now the patch looks like this:

--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -409,6 +409,29 @@ static void mtk_pcie_enable_msi(struct m
 	writel_relaxed(val, pcie->base + PCIE_INT_ENABLE_REG);
 }
 
+static int mtk_pcie_link_up_error(struct mtk_gen3_pcie *pcie)
+{
+	/* Check if the link is up or not */
+	int err;
+	u32 val;
+	err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val,
+				 !!(val & PCIE_PORT_LINKUP), 20,
+				 PCI_PM_D3COLD_WAIT * USEC_PER_MSEC);
+	if (err) {
+		const char *ltssm_state;
+		int ltssm_index;
+
+		val = readl_relaxed(pcie->base + PCIE_LTSSM_STATUS_REG);
+		ltssm_index = PCIE_LTSSM_STATE(val);
+		ltssm_state = ltssm_index >= ARRAY_SIZE(ltssm_str) ?
+			      "Unknown state" : ltssm_str[ltssm_index];
+		dev_err(pcie->dev,
+			"PCIe link down, current LTSSM state: %s (%#x)\n",
+			ltssm_state, val);
+	}
+	return err;
+}
+
 static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
 {
 	struct resource_entry *entry;
@@ -499,28 +522,31 @@ static int mtk_pcie_startup_port(struct
 		msleep(PCIE_T_PVPERL_MS);
 
 		/* De-assert reset signals */
-		val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
-			 PCIE_PE_RSTB);
+		val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB);
 		writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
-	}
 
-	/* Check if the link is up or not */
-	err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val,
-				 !!(val & PCIE_PORT_LINKUP), 20,
-				 PCI_PM_D3COLD_WAIT * USEC_PER_MSEC);
-	if (err) {
-		const char *ltssm_state;
-		int ltssm_index;
+		int retries = 1;
+		while (retries <= 10) {
+			msleep(PCIE_T_PVPERL_MS);
+
+			/* De-assert PERST# signal */
+			val &= ~(PCIE_PE_RSTB);
+			writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
+
+			err = mtk_pcie_link_up_error(pcie);
+			if(!err) {
+				break;
+			}
+
+			val |= PCIE_PE_RSTB;
+			writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
+			retries++;
+		}
+	}
 
-		val = readl_relaxed(pcie->base + PCIE_LTSSM_STATUS_REG);
-		ltssm_index = PCIE_LTSSM_STATE(val);
-		ltssm_state = ltssm_index >= ARRAY_SIZE(ltssm_str) ?
-			      "Unknown state" : ltssm_str[ltssm_index];
-		dev_err(pcie->dev,
-			"PCIe link down, current LTSSM state: %s (%#x)\n",
-			ltssm_state, val);
+	err = mtk_pcie_link_up_error(pcie);
+	if(err)
 		return err;
-	}
 
 	mtk_pcie_enable_msi(pcie);

With this, i was thinking that dmesg will show repeated PCIe link down, current LTSSM state: recovery.equalization, but it only shows one, it looks like only the first one failed and i don’t know why with my second test with 200 ms did not worked. Now SSD is alive on first boot and reboot.

Hope it helps somebody else.

Thank you!

1 Like

Glad it now works for you.

I thought about creating an OpenWrt PR with my version of 611; you’re saying it doesn’t solve your problem? same dmesg errors? which SSD do you use?

With your version, and with mine, being both so similar, it did not worked on cold boot. Same log: PCIe link down, current LTSSM state: recovery.equalization

With this new patch i shared with you, it worked on cold and warm boot.

My SSD is Adata Legend 710, 1 TB.

Please note - my bad - because i’m working on R4 and this thread is for R3. Both use gen 3 driver, so that’s why i stilled asking here.