* [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable @ 2026-06-14 1:56 Gowtham Kudupudi 2026-06-15 10:34 ` Ronald Claveau 0 siblings, 1 reply; 5+ messages in thread From: Gowtham Kudupudi @ 2026-06-14 1:56 UTC (permalink / raw) To: yue.wang, lpieralisi, kwilczynski, mani Cc: robh, bhelgaas, neil.armstrong, khilman, jbrunet, martin.blumenstingl, linux-pci, linux-amlogic, linux-arm-kernel, linux-kernel, Gowtham Kudupudi On warm reboot, the PCIe controller's LTSSM starts link training immediately if PERST# is already deasserted from the previous boot. The driver then pulses PERST# for only 500us, which is too short to properly reset the endpoint device that has already started training. Fix by moving the PERST# assert/deassert pulse BEFORE enabling LTSSM, so the endpoint gets a clean reset cycle before link training begins. This was found on Amlogic G12B (A311D) with NVMe on an M.2 slot. Cold boot worked because POR held PERST# low; warm reboot did not. The fix was confirmed on a Banana Pi CM4 with Waveshare IO base board. Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com> --- drivers/pci/controller/dwc/pci-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index 5f8e2f4b3c12..3a7e9f1d5b8c 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -310,8 +310,8 @@ static int meson_pcie_start_link(struct dw_pcie *pci) { struct meson_pcie *mp = to_meson_pcie(pci); + meson_pcie_assert_reset(mp); meson_pcie_ltssm_enable(mp); - meson_pcie_assert_reset(mp); return 0; } -- 2.49.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable 2026-06-14 1:56 [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable Gowtham Kudupudi @ 2026-06-15 10:34 ` Ronald Claveau 2026-06-16 6:06 ` neil.armstrong 0 siblings, 1 reply; 5+ messages in thread From: Ronald Claveau @ 2026-06-15 10:34 UTC (permalink / raw) To: Gowtham Kudupudi Cc: robh, bhelgaas, neil.armstrong, khilman, jbrunet, martin.blumenstingl, linux-pci, linux-amlogic, linux-arm-kernel, linux-kernel, yue.wang, lpieralisi, kwilczynski, mani On 6/14/26 3:56 AM, Gowtham Kudupudi wrote: > On warm reboot, the PCIe controller's LTSSM starts link training > immediately if PERST# is already deasserted from the previous boot. > The driver then pulses PERST# for only 500us, which is too short to > properly reset the endpoint device that has already started training. > > Fix by moving the PERST# assert/deassert pulse BEFORE enabling LTSSM, > so the endpoint gets a clean reset cycle before link training begins. > > This was found on Amlogic G12B (A311D) with NVMe on an M.2 slot. > Cold boot worked because POR held PERST# low; warm reboot did not. > The fix was confirmed on a Banana Pi CM4 with Waveshare IO base board. > > Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com> > --- > drivers/pci/controller/dwc/pci-meson.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c > index 5f8e2f4b3c12..3a7e9f1d5b8c 100644 > --- a/drivers/pci/controller/dwc/pci-meson.c > +++ b/drivers/pci/controller/dwc/pci-meson.c > @@ -310,8 +310,8 @@ static int meson_pcie_start_link(struct dw_pcie *pci) > { > struct meson_pcie *mp = to_meson_pcie(pci); > > + meson_pcie_assert_reset(mp); > meson_pcie_ltssm_enable(mp); > - meson_pcie_assert_reset(mp); > > return 0; > } Hi Gowtham, I have a patch [1] that I haven't submitted yet. This might be related to your issue, what do you think ? [1] https://github.com/rclaveau-tech/linux-khadas/commit/bee0a02d9756 -- Best regards, Ronald ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable 2026-06-15 10:34 ` Ronald Claveau @ 2026-06-16 6:06 ` neil.armstrong 2026-06-16 23:36 ` gowtham 0 siblings, 1 reply; 5+ messages in thread From: neil.armstrong @ 2026-06-16 6:06 UTC (permalink / raw) To: Ronald Claveau, Gowtham Kudupudi Cc: robh, bhelgaas, khilman, jbrunet, martin.blumenstingl, linux-pci, linux-amlogic, linux-arm-kernel, linux-kernel, yue.wang, lpieralisi, kwilczynski, mani On 6/15/26 12:34, Ronald Claveau wrote: > On 6/14/26 3:56 AM, Gowtham Kudupudi wrote: >> On warm reboot, the PCIe controller's LTSSM starts link training >> immediately if PERST# is already deasserted from the previous boot. >> The driver then pulses PERST# for only 500us, which is too short to >> properly reset the endpoint device that has already started training. >> >> Fix by moving the PERST# assert/deassert pulse BEFORE enabling LTSSM, >> so the endpoint gets a clean reset cycle before link training begins. >> >> This was found on Amlogic G12B (A311D) with NVMe on an M.2 slot. >> Cold boot worked because POR held PERST# low; warm reboot did not. >> The fix was confirmed on a Banana Pi CM4 with Waveshare IO base board. >> >> Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com> >> --- >> drivers/pci/controller/dwc/pci-meson.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c >> index 5f8e2f4b3c12..3a7e9f1d5b8c 100644 >> --- a/drivers/pci/controller/dwc/pci-meson.c >> +++ b/drivers/pci/controller/dwc/pci-meson.c >> @@ -310,8 +310,8 @@ static int meson_pcie_start_link(struct dw_pcie *pci) >> { >> struct meson_pcie *mp = to_meson_pcie(pci); >> >> + meson_pcie_assert_reset(mp); >> meson_pcie_ltssm_enable(mp); >> - meson_pcie_assert_reset(mp); I think this change is valid, other controllers resets PERST in the host init callback, so either this or move to the init callback. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> >> >> return 0; >> } > > Hi Gowtham, > > I have a patch [1] that I haven't submitted yet. > This might be related to your issue, what do you think ? Ronald, This fix is valid, it's definitely better to probe the driver with PERST asserted, please send it. Neil > > [1] https://github.com/rclaveau-tech/linux-khadas/commit/bee0a02d9756 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable 2026-06-16 6:06 ` neil.armstrong @ 2026-06-16 23:36 ` gowtham 2026-06-17 20:30 ` gowtham 0 siblings, 1 reply; 5+ messages in thread From: gowtham @ 2026-06-16 23:36 UTC (permalink / raw) To: neil.armstrong Cc: Ronald Claveau, robh, bhelgaas, khilman, jbrunet, martin.blumenstingl, linux-pci, linux-amlogic, linux-arm-kernel, linux-kernel, yue.wang, lpieralisi, kwilczynski, mani Hi, As Neil suggested I moved the PCIe reset to init; I've updated the tag at https://github.com/GowthamKudupudi/linux/tree/meson-pcie-warm-reset-linux-7.0.y Ronald, yes, I do think its proper to initialize PCIe with RESET Active. Anyway we need the reset *cycle*. Please submit your patch as well. Thank you! ...Gowtham On Tue, 16 Jun 2026 08:06:02 +0200 neil.armstrong@linaro.org wrote: > On 6/15/26 12:34, Ronald Claveau wrote: > > On 6/14/26 3:56 AM, Gowtham Kudupudi wrote: > >> On warm reboot, the PCIe controller's LTSSM starts link training > >> immediately if PERST# is already deasserted from the previous boot. > >> The driver then pulses PERST# for only 500us, which is too short to > >> properly reset the endpoint device that has already started > >> training. > >> > >> Fix by moving the PERST# assert/deassert pulse BEFORE enabling > >> LTSSM, so the endpoint gets a clean reset cycle before link > >> training begins. > >> > >> This was found on Amlogic G12B (A311D) with NVMe on an M.2 slot. > >> Cold boot worked because POR held PERST# low; warm reboot did not. > >> The fix was confirmed on a Banana Pi CM4 with Waveshare IO base > >> board. > >> > >> Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com> > >> --- > >> drivers/pci/controller/dwc/pci-meson.c | 2 +- > >> 1 file changed, 1 insertion(+), 1 deletion(-) > >> > >> diff --git a/drivers/pci/controller/dwc/pci-meson.c > >> b/drivers/pci/controller/dwc/pci-meson.c index > >> 5f8e2f4b3c12..3a7e9f1d5b8c 100644 --- > >> a/drivers/pci/controller/dwc/pci-meson.c +++ > >> b/drivers/pci/controller/dwc/pci-meson.c @@ -310,8 +310,8 @@ > >> static int meson_pcie_start_link(struct dw_pcie *pci) { > >> struct meson_pcie *mp = to_meson_pcie(pci); > >> > >> + meson_pcie_assert_reset(mp); > >> meson_pcie_ltssm_enable(mp); > >> - meson_pcie_assert_reset(mp); > > I think this change is valid, other controllers resets PERST > in the host init callback, so either this or move to the > init callback. > > Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> > > >> > >> return 0; > >> } > > > > Hi Gowtham, > > > > I have a patch [1] that I haven't submitted yet. > > This might be related to your issue, what do you think ? > > Ronald, This fix is valid, it's definitely better to probe the > driver with PERST asserted, please send it. > > Neil > > > > > [1] > > https://github.com/rclaveau-tech/linux-khadas/commit/bee0a02d9756 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable 2026-06-16 23:36 ` gowtham @ 2026-06-17 20:30 ` gowtham 0 siblings, 0 replies; 5+ messages in thread From: gowtham @ 2026-06-17 20:30 UTC (permalink / raw) To: neil.armstrong Cc: Ronald Claveau, robh, bhelgaas, khilman, jbrunet, martin.blumenstingl, linux-pci, linux-amlogic, linux-arm-kernel, linux-kernel, yue.wang, lpieralisi, kwilczynski, mani [-- Attachment #1: Type: text/plain, Size: 4506 bytes --] Hi Ronald, I see you submitted the patch. Last couple of days I've been fixing the etherenet of my BPiCM4+Waveshare-io-base-b due to which I couldn't test your patch any sooner. Now I got my ethernet working but now I couldn't reproduce the issue *without* either of our patches!!! Anyway it's proper to initialize PCIe with RESET Active but I think meson_pcie_assert_reset(mp) will give sufficient time to PCIe devices to complete the reset cycle. --- drivers/pci/controller/dwc/pci-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index 0694084f612..c28ab40c9ff 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -308,8 +308,8 @@ static int meson_pcie_start_link(struct dw_pcie *pci) { struct meson_pcie *mp = to_meson_pcie(pci); - meson_pcie_ltssm_enable(mp); meson_pcie_assert_reset(mp); + meson_pcie_ltssm_enable(mp); return 0; } -- --- drivers/pci/controller/dwc/pci-meson.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index c28ab40c9ff..2ef75157530 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -308,7 +308,6 @@ static int meson_pcie_start_link(struct dw_pcie *pci) { struct meson_pcie *mp = to_meson_pcie(pci); - meson_pcie_assert_reset(mp); meson_pcie_ltssm_enable(mp); return 0; @@ -362,6 +361,8 @@ static int meson_pcie_host_init(struct dw_pcie_rp *pp) pp->bridge->ops = &meson_pci_ops; + meson_pcie_assert_reset(mp); + meson_set_max_payload(mp, MAX_PAYLOAD_SIZE); meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE); -- ...Gowtham On Wed, 17 Jun 2026 05:06:27 +0530 gowtham <gowtham@ferryfair.com> wrote: > Hi, > > As Neil suggested I moved the PCIe reset to init; I've updated the tag > at > https://github.com/GowthamKudupudi/linux/tree/meson-pcie-warm-reset-linux-7.0.y > > Ronald, yes, I do think its proper to initialize PCIe with RESET > Active. Anyway we need the reset *cycle*. Please submit your patch as > well. > > Thank you! > > ...Gowtham > > On Tue, 16 Jun 2026 08:06:02 +0200 > neil.armstrong@linaro.org wrote: > > > On 6/15/26 12:34, Ronald Claveau wrote: > > > On 6/14/26 3:56 AM, Gowtham Kudupudi wrote: > > >> On warm reboot, the PCIe controller's LTSSM starts link training > > >> immediately if PERST# is already deasserted from the previous > > >> boot. The driver then pulses PERST# for only 500us, which is too > > >> short to properly reset the endpoint device that has already > > >> started training. > > >> > > >> Fix by moving the PERST# assert/deassert pulse BEFORE enabling > > >> LTSSM, so the endpoint gets a clean reset cycle before link > > >> training begins. > > >> > > >> This was found on Amlogic G12B (A311D) with NVMe on an M.2 slot. > > >> Cold boot worked because POR held PERST# low; warm reboot did > > >> not. The fix was confirmed on a Banana Pi CM4 with Waveshare IO > > >> base board. > > >> > > >> Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com> > > >> --- > > >> drivers/pci/controller/dwc/pci-meson.c | 2 +- > > >> 1 file changed, 1 insertion(+), 1 deletion(-) > > >> > > >> diff --git a/drivers/pci/controller/dwc/pci-meson.c > > >> b/drivers/pci/controller/dwc/pci-meson.c index > > >> 5f8e2f4b3c12..3a7e9f1d5b8c 100644 --- > > >> a/drivers/pci/controller/dwc/pci-meson.c +++ > > >> b/drivers/pci/controller/dwc/pci-meson.c @@ -310,8 +310,8 @@ > > >> static int meson_pcie_start_link(struct dw_pcie *pci) { > > >> struct meson_pcie *mp = to_meson_pcie(pci); > > >> > > >> + meson_pcie_assert_reset(mp); > > >> meson_pcie_ltssm_enable(mp); > > >> - meson_pcie_assert_reset(mp); > > > > I think this change is valid, other controllers resets PERST > > in the host init callback, so either this or move to the > > init callback. > > > > Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> > > > > >> > > >> return 0; > > >> } > > > > > > Hi Gowtham, > > > > > > I have a patch [1] that I haven't submitted yet. > > > This might be related to your issue, what do you think ? > > > > Ronald, This fix is valid, it's definitely better to probe the > > driver with PERST asserted, please send it. > > > > Neil > > > > > > > > [1] > > > https://github.com/rclaveau-tech/linux-khadas/commit/bee0a02d9756 > > > > > > [-- Attachment #2: 0001-PCI-meson-Fix-PERST-timing-by-asserting-reset-before.patch --] [-- Type: text/x-patch, Size: 1488 bytes --] From 852811b11795ee389ea6a953ed0db69b76722469 Mon Sep 17 00:00:00 2001 From: Gowtham Kudupudi <gowtham@ferryfair.com> Date: Sun, 14 Jun 2026 09:41:01 +0530 Subject: [PATCH 1/2] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable On warm reboot, the PCIe controller's LTSSM starts link training immediately if PERST# is already deasserted from the previous boot. The driver then pulses PERST# for only 500us, which is too short to properly reset the endpoint device that has already started training. Fix by moving the PERST# assert/deassert pulse BEFORE enabling LTSSM, so the endpoint gets a clean reset cycle before link training begins. This was found on Amlogic G12B (A311D) with NVMe on an M.2 slot. Cold boot worked because POR held PERST# low; warm reboot did not. The fix was confirmed on a Banana Pi CM4 with Waveshare IO base board. Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com> --- drivers/pci/controller/dwc/pci-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index 0694084f612..c28ab40c9ff 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -308,8 +308,8 @@ static int meson_pcie_start_link(struct dw_pcie *pci) { struct meson_pcie *mp = to_meson_pcie(pci); - meson_pcie_ltssm_enable(mp); meson_pcie_assert_reset(mp); + meson_pcie_ltssm_enable(mp); return 0; } -- 2.54.0 [-- Attachment #3: 0002-PCI-meson-pcie-reset-moved-to-meson_pcie_host_init.patch --] [-- Type: text/x-patch, Size: 1159 bytes --] From 1bcf2c787d72b2c25852cc598b1201510b4132b0 Mon Sep 17 00:00:00 2001 From: Gowtham Kudupudi <gowtham@ferryfair.com> Date: Wed, 17 Jun 2026 04:29:45 +0530 Subject: [PATCH 2/2] PCI: meson: pcie reset moved to meson_pcie_host_init As per the Neil's suggestion, inititial PCIe reset is moved to init to make it proper. Signed-off-by: Gowtham Kudupudi <gowtham@ferryfair.com> --- drivers/pci/controller/dwc/pci-meson.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index c28ab40c9ff..2ef75157530 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -308,7 +308,6 @@ static int meson_pcie_start_link(struct dw_pcie *pci) { struct meson_pcie *mp = to_meson_pcie(pci); - meson_pcie_assert_reset(mp); meson_pcie_ltssm_enable(mp); return 0; @@ -362,6 +361,8 @@ static int meson_pcie_host_init(struct dw_pcie_rp *pp) pp->bridge->ops = &meson_pci_ops; + meson_pcie_assert_reset(mp); + meson_set_max_payload(mp, MAX_PAYLOAD_SIZE); meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE); -- 2.54.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-17 20:31 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-14 1:56 [PATCH] PCI: meson: Fix PERST# timing by asserting reset before LTSSM enable Gowtham Kudupudi 2026-06-15 10:34 ` Ronald Claveau 2026-06-16 6:06 ` neil.armstrong 2026-06-16 23:36 ` gowtham 2026-06-17 20:30 ` gowtham
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox