* [PATCH RFC 1/2] PCI: rockchip-host: Retry link training that times out
2026-10-24 1:02 [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399 Igor Velkov via B4 Relay
@ 2026-10-24 1:02 ` Igor Velkov via B4 Relay
2026-10-24 1:02 ` [PATCH RFC 2/2] PCI: rockchip-host: Hot-reset the endpoint before using the link Igor Velkov via B4 Relay
2026-10-26 9:08 ` [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399 Shawn Lin
2 siblings, 0 replies; 7+ messages in thread
From: Igor Velkov via B4 Relay @ 2026-10-24 1:02 UTC (permalink / raw)
To: Shawn Lin, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas
Cc: Rob Herring, Heiko Stuebner, linux-pci, linux-rockchip,
linux-arm-kernel, linux-kernel, Igor Velkov
From: Igor Velkov <iav@iav.lv>
On a Kobol Helios64 the JMB585 SATA controller sometimes does not train
the link on resume from s2idle. The 500 ms poll times out and
resume_noirq() returns -ETIMEDOUT. On v7.3-rc7 with the mainline DT
this happened in the 14th of 14 cycles, and the system did not resume.
When training times out, bring the port up again, at most twice. Each
attempt initializes the PHYs again and, where PERST# is wired, holds it
low for at least 100 ms. Without an endpoint, probe now gives up after
three attempts, in about 2.1 s instead of 0.7 s.
Print the LTSSM state with the timeout message.
With the patch, one such timeout showed LTSSM 0x10, and the first retry
trained the link.
Assisted-by: LLM
Signed-off-by: Igor Velkov <iav@iav.lv>
---
drivers/pci/controller/pcie-rockchip-host.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index 5b071bdc4f90..b4499fc3f90b 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -325,7 +325,10 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
status, PCIE_LINK_UP(status), 20,
500 * USEC_PER_MSEC);
if (err) {
- dev_err(dev, "PCIe link training gen1 timeout!\n");
+ status = rockchip_pcie_read(rockchip, PCIE_CLIENT_DEBUG_OUT_0) &
+ PCIE_CLIENT_DEBUG_LTSSM_MASK;
+ dev_err(dev, "PCIe link training gen1 timeout! (LTSSM %#x)\n",
+ status);
goto err_power_off_phy;
}
@@ -377,6 +380,26 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
return err;
}
+#define ROCKCHIP_PCIE_INIT_RETRIES 2
+
+/* Pulse PERST# and train again when the link does not come up */
+static int rockchip_pcie_init_port_retry(struct rockchip_pcie *rockchip)
+{
+ struct device *dev = rockchip->dev;
+ int i, err;
+
+ for (i = 0; ; i++) {
+ err = rockchip_pcie_host_init_port(rockchip);
+ if (err != -ETIMEDOUT || i == ROCKCHIP_PCIE_INIT_RETRIES)
+ break;
+ dev_info(dev, "link training retry %d\n", i + 1);
+ }
+
+ if (!err && i)
+ dev_info(dev, "link up after %d retries\n", i);
+ return err;
+}
+
static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
{
struct rockchip_pcie *rockchip = arg;
@@ -881,7 +904,7 @@ static int rockchip_pcie_resume_noirq(struct device *dev)
if (err)
goto err_disable_0v9;
- err = rockchip_pcie_host_init_port(rockchip);
+ err = rockchip_pcie_init_port_retry(rockchip);
if (err)
goto err_pcie_resume;
@@ -938,7 +961,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
goto err_set_vpcie;
}
- err = rockchip_pcie_host_init_port(rockchip);
+ err = rockchip_pcie_init_port_retry(rockchip);
if (err)
goto err_vpcie;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH RFC 2/2] PCI: rockchip-host: Hot-reset the endpoint before using the link
2026-10-24 1:02 [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399 Igor Velkov via B4 Relay
2026-10-24 1:02 ` [PATCH RFC 1/2] PCI: rockchip-host: Retry link training that times out Igor Velkov via B4 Relay
@ 2026-10-24 1:02 ` Igor Velkov via B4 Relay
2026-10-26 9:08 ` [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399 Shawn Lin
2 siblings, 0 replies; 7+ messages in thread
From: Igor Velkov via B4 Relay @ 2026-10-24 1:02 UTC (permalink / raw)
To: Shawn Lin, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas
Cc: Rob Herring, Heiko Stuebner, linux-pci, linux-rockchip,
linux-arm-kernel, linux-kernel, Igor Velkov
From: Igor Velkov <iav@iav.lv>
On a Kobol Helios64 the JMB585 sometimes trains the link but does not
answer config reads. On resume, a read in rockchip_pcie_rd_conf(),
called from pci_power_up(), ends in a synchronous external abort and
the kernel oopses. At probe, a config read during the bus scan ended in
an SError on 1 of 4 boots of v7.3-rc7.
After training, hot-reset the endpoint, hold the reset at least 2 ms as
pci_reset_secondary_bus() does, and wait for the link. Clear the AXI
link-down status (CDNS_PCIE_AT_LINKDOWN in the Cadence host driver),
then wait the 100 ms required after a Conventional Reset. Fail probe
and resume if the hot reset fails.
s2idle on v7.3-rc7 with the mainline DT and patch 1:
sleep without this patch with it
~40 s 2 aborts / 30 0 / 100
~25 s 1 abort / 11 0 / 40, then 2 aborts in the next 3
After the hot reset the link came back in 2.8-2.9 ms in the good
cycles. In the last abort it came back in 25 ms, and the next config
read aborted. The other abort left no timing. Boots with the patch were
not counted.
Print how long the link took to come back. This explains the data
above and helps anyone who runs the code.
Assisted-by: LLM
Signed-off-by: Igor Velkov <iav@iav.lv>
---
drivers/pci/controller/pcie-rockchip-host.c | 59 +++++++++++++++++++++++++++++
drivers/pci/controller/pcie-rockchip.h | 4 ++
2 files changed, 63 insertions(+)
diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index b4499fc3f90b..f75c2c8358f5 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -400,6 +400,57 @@ static int rockchip_pcie_init_port_retry(struct rockchip_pcie *rockchip)
return err;
}
+/* Hot-reset the endpoint; *link_us: time until the link came back, 0 if not reset */
+static int rockchip_pcie_hot_reset(struct rockchip_pcie *rockchip, s64 *link_us)
+{
+ u32 status;
+ ktime_t start;
+ int err;
+
+ *link_us = 0;
+ rockchip_pcie_write(rockchip, PCIE_CLIENT_HOT_RESET_ASSERT,
+ PCIE_CLIENT_HOT_RESET_CTRL);
+ err = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_INT_STATUS,
+ status, status & PCIE_CLIENT_INT_HOT_RST,
+ 100, 100 * USEC_PER_MSEC);
+ rockchip_pcie_write(rockchip, PCIE_CLIENT_INT_HOT_RST,
+ PCIE_CLIENT_INT_STATUS);
+ /* Hold the reset at least 2 ms, as pci_reset_secondary_bus() does */
+ if (!err)
+ usleep_range(2000, 3000);
+ rockchip_pcie_write(rockchip, PCIE_CLIENT_HOT_RESET_DEASSERT,
+ PCIE_CLIENT_HOT_RESET_CTRL);
+ if (err)
+ return err;
+
+ start = ktime_get();
+ err = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_BASIC_STATUS1,
+ status, PCIE_LINK_UP(status), 20,
+ LINK_TRAIN_TIMEOUT);
+ *link_us = ktime_us_delta(ktime_get(), start);
+
+ /* Clear the AXI link-down status before config traffic, as the Cadence host driver does */
+ rockchip_pcie_write(rockchip, 0, PCIE_CORE_AXI_LINK_DOWN);
+
+ return err;
+}
+
+/* A JMB585 sometimes comes out of reset unable to answer config requests */
+static int rockchip_pcie_reset_endpoint(struct rockchip_pcie *rockchip)
+{
+ struct device *dev = rockchip->dev;
+ s64 link_us;
+ int err;
+
+ err = rockchip_pcie_hot_reset(rockchip, &link_us);
+ dev_info(dev, "hot reset: link back in %lld us, err %d\n", link_us, err);
+ if (err)
+ return err;
+
+ msleep(PCIE_RESET_CONFIG_WAIT_MS);
+ return 0;
+}
+
static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
{
struct rockchip_pcie *rockchip = arg;
@@ -908,6 +959,10 @@ static int rockchip_pcie_resume_noirq(struct device *dev)
if (err)
goto err_pcie_resume;
+ err = rockchip_pcie_reset_endpoint(rockchip);
+ if (err)
+ goto err_err_deinit_port;
+
err = rockchip_pcie_cfg_atu(rockchip);
if (err)
goto err_err_deinit_port;
@@ -965,6 +1020,10 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
if (err)
goto err_vpcie;
+ err = rockchip_pcie_reset_endpoint(rockchip);
+ if (err)
+ goto err_deinit_port;
+
err = rockchip_pcie_init_irq_domain(rockchip);
if (err < 0)
goto err_deinit_port;
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index b5da15601b58..4509e044862b 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -47,6 +47,9 @@
#define PCIE_CLIENT_INT_IN_DEASSERT HWORD_CLR_BIT(0x0002)
#define PCIE_CLIENT_INT_PEND_ST_PEND HWORD_SET_BIT(0x0001)
#define PCIE_CLIENT_INT_PEND_ST_NORMAL HWORD_CLR_BIT(0x0001)
+#define PCIE_CLIENT_HOT_RESET_CTRL (PCIE_CLIENT_BASE + 0x18)
+#define PCIE_CLIENT_HOT_RESET_ASSERT HWORD_SET_BIT(0x0001)
+#define PCIE_CLIENT_HOT_RESET_DEASSERT HWORD_CLR_BIT(0x0001)
#define PCIE_CLIENT_SIDE_BAND_STATUS (PCIE_CLIENT_BASE + 0x20)
#define PCIE_CLIENT_PHY_ST BIT(12)
#define PCIE_CLIENT_DEBUG_OUT_0 (PCIE_CLIENT_BASE + 0x3c)
@@ -170,6 +173,7 @@
#define PCIE_CORE_OB_REGION_ADDR1 (PCIE_CORE_AXI_CONF_BASE + 0x4)
#define PCIE_CORE_OB_REGION_DESC0 (PCIE_CORE_AXI_CONF_BASE + 0x8)
#define PCIE_CORE_OB_REGION_DESC1 (PCIE_CORE_AXI_CONF_BASE + 0xc)
+#define PCIE_CORE_AXI_LINK_DOWN (PCIE_CORE_AXI_CONF_BASE + 0x824)
#define PCIE_CORE_AXI_INBOUND_BASE 0xc00800
#define PCIE_RP_IB_ADDR0 (PCIE_CORE_AXI_INBOUND_BASE + 0x0)
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399
2026-10-24 1:02 [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399 Igor Velkov via B4 Relay
2026-10-24 1:02 ` [PATCH RFC 1/2] PCI: rockchip-host: Retry link training that times out Igor Velkov via B4 Relay
2026-10-24 1:02 ` [PATCH RFC 2/2] PCI: rockchip-host: Hot-reset the endpoint before using the link Igor Velkov via B4 Relay
@ 2026-10-26 9:08 ` Shawn Lin
2026-10-26 18:28 ` Igor Velkov
2 siblings, 1 reply; 7+ messages in thread
From: Shawn Lin @ 2026-10-26 9:08 UTC (permalink / raw)
To: iav, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas
Cc: shawn.lin, Rob Herring, Heiko Stuebner, linux-pci,
linux-rockchip, linux-arm-kernel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3171 bytes --]
Hi Igor,
在 2026/10/24 星期六 9:02, Igor Velkov via B4 Relay 写道:
> How should the host recover an endpoint that trains the link but does
> not answer config requests? On RK3399 that read ends in an external
> abort (an SError at probe, a synchronous abort on resume), and the
> kernel oopses instead of seeing an absent device.
>
> This happens on a Kobol Helios64 (RK3399, JMicron JMB585 SATA) with
> v7.3-rc7 and the mainline DT, in two forms:
>
> - link training times out on resume from s2idle (patch 1);
> - the link trains, but a config read of the JMB585 aborts in
> pci_power_up() during resume, and during the bus scan at probe on
> 1 of 4 boots (patch 2).
>
> Patch 1 trains again after a timeout. Patch 2 hot-resets the endpoint
> after training and waits the 100 ms required after a Conventional
> Reset, so every RK3399 probe and resume takes ~105 ms longer.
>
> s2idle with both patches:
>
> sleep patch 1 only both patches
> ~40 s 2 aborts / 30 0 / 100
> ~25 s 1 abort / 11 0 / 40, then 2 aborts in the next 3
>
> In the last of those aborts the link came back 25 ms after the hot
> reset instead of 2.8-2.9 ms, and the endpoint did not answer. We could
> not reproduce that state on demand.
>
> host_init_port() already pulses PERST# and waits 100 ms before link
> training, so config reads start as soon as the link is up. Waiting 1 s
> after link-up before the bus scan did not help: 2 of 2 rebinds aborted,
> against 2 of 25 without the wait. That test ran without PERST# (the DT
> had no ep-gpios).
>
> The data is from the code as posted, except that patch 2 now also fails
> probe and resume when the hot reset itself fails; that path was not hit.
>
> Questions:
> 1. Is an unconditional hot reset after training acceptable, or should
> it depend on the board?
Probably it depends on the board.
> 2. Can the host tell before a config read that the endpoint will not
> answer?
The host cannot distinguish this case. If the endpoint has not prepared
to respond to a configuration read TLP, the controller should return all
ones to the AXI bus instead of triggering a SError. Unfortunately, this
is a limitation of the RK3399.
> 3. Is PERST# or a power cycle of the slot the expected recovery from a
> slow link after the hot reset?
You've tried PERST# with the patch 1 applied. So perhaps it's doesn't
help.
> 4. Should the reset be a Secondary Bus Reset through the Root Port
> rather than PCIE_CLIENT_HOT_RESET_CTRL? We did not try it.
>
They are identical from the endpoint's point of view.
I've attached a vendor's debug patch, perhaps you could try it without
your patch.
> ---
> Igor Velkov (2):
> PCI: rockchip-host: Retry link training that times out
> PCI: rockchip-host: Hot-reset the endpoint before using the link
>
> drivers/pci/controller/pcie-rockchip-host.c | 88 ++++++++++++++++++++++++++++-
> drivers/pci/controller/pcie-rockchip.h | 4 ++
> 2 files changed, 89 insertions(+), 3 deletions(-)
> ---
> base-commit: 732c4f7d2c04f8c175d85d9243213783ee024ebc
> change-id: 20261018-rockchip-pcie-resume-2c4dfe23341e
>
> Best regards,
[-- Attachment #2: 0001-arm64-pci-rockchip-Add-a-SError-handler-hook-for-the.patch --]
[-- Type: text/plain, Size: 4551 bytes --]
From 9b145593a514d0b5cd4e710129d60c54f2368e2e Mon Sep 17 00:00:00 2001
From: Shawn Lin <shawn.lin@rock-chips.com>
Date: Mon, 26 Oct 2026 16:55:32 +0800
Subject: [PATCH] arm64: pci: rockchip: Add a SError handler hook for the PCIe
host
Some RK3399 boards with a PCIe switch behind the Rockchip host
controller see a config read end in a synchronous external abort, which
do_serror() treats as fatal and panics the kernel.
Allow a platform driver to install a handler for SError. The handler
runs before the default handling and, when it returns 0, the error is
considered handled and the kernel keeps running. Give it the faulting
address from FAR_EL1 and the ESR value, so the handler can decide
whether the error belongs to its device.
The Rockchip PCIe host driver registers such a handler once the link is
up and just logs the address and ESR for now.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
arch/arm64/include/asm/system_misc.h | 3 +++
arch/arm64/kernel/traps.c | 18 ++++++++++++++++++
drivers/pci/controller/pcie-rockchip-host.c | 17 +++++++++++++++++
drivers/pci/controller/pcie-rockchip.h | 5 +++++
4 files changed, 43 insertions(+)
diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
index d316a804eb38..299839f517eb 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -25,6 +25,9 @@ void arm64_notify_die(const char *str, struct pt_regs *regs,
int signo, int sicode, unsigned long far,
unsigned long err);
+void *hook_serror_handler(int (*fn)(unsigned long, unsigned long,
+ struct pt_regs *));
+
struct mm_struct;
extern void __show_regs(struct pt_regs *);
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index d6391ab20db3..d87bd1bd0ee8 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -946,6 +946,9 @@ void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr)
cpu_park_loop();
}
+static int (*serror_handler)(unsigned long, unsigned long,
+ struct pt_regs *) __ro_after_init;
+
bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr)
{
unsigned long aet = arm64_ras_serror_get_severity(esr);
@@ -980,11 +983,26 @@ bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr)
void do_serror(struct pt_regs *regs, unsigned long esr)
{
+ unsigned long addr = read_sysreg(far_el1);
+
+ if (serror_handler && !serror_handler(addr, esr, regs))
+ return;
+
/* non-RAS errors are not containable */
if (!arm64_is_ras_serror(esr) || arm64_is_fatal_ras_serror(regs, esr))
arm64_serror_panic(regs, esr);
}
+void *hook_serror_handler(int (*fn)(unsigned long, unsigned long,
+ struct pt_regs *))
+{
+ void *ret = serror_handler;
+
+ serror_handler = fn;
+
+ return ret;
+}
+
/* GENERIC_BUG traps */
#ifdef CONFIG_GENERIC_BUG
int is_valid_bugaddr(unsigned long addr)
diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index 5b071bdc4f90..4640adee127a 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -904,6 +904,19 @@ static int rockchip_pcie_resume_noirq(struct device *dev)
return err;
}
+#ifdef CONFIG_ARM64
+static int (*serror_chain)(unsigned long addr, unsigned long esr,
+ struct pt_regs *regs);
+
+static int do_rockchip_pcie_serror(unsigned long addr, unsigned long esr,
+ struct pt_regs *regs)
+{
+ pr_info("rockchip-pcie: SError handled, addr %#lx esr %#lx\n",
+ addr, esr);
+ return 0;
+}
+#endif
+
static int rockchip_pcie_probe(struct platform_device *pdev)
{
struct rockchip_pcie *rockchip;
@@ -969,6 +982,10 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
if (err < 0)
goto err_remove_irq_domain;
+#ifdef CONFIG_ARM64
+ serror_chain = hook_serror_handler(do_rockchip_pcie_serror);
+#endif
+
return 0;
err_remove_irq_domain:
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index b5da15601b58..291befcdf6c3 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -18,6 +18,11 @@
#include <linux/pci-ecam.h>
#include <linux/reset.h>
+#ifdef CONFIG_ARM64
+#include <asm/signal.h>
+#include <asm/system_misc.h>
+#endif
+
/*
* The upper 16 bits of PCIE_CLIENT_CONFIG are a write mask for the lower 16
* bits. This allows atomic updates of the register without locking.
--
2.25.1
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399
2026-10-26 9:08 ` [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399 Shawn Lin
@ 2026-10-26 18:28 ` Igor Velkov
2026-10-27 0:44 ` Shawn Lin
0 siblings, 1 reply; 7+ messages in thread
From: Igor Velkov @ 2026-10-26 18:28 UTC (permalink / raw)
To: Shawn Lin
Cc: Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Rob Herring,
Heiko Stuebner, linux-pci, linux-rockchip, linux-arm-kernel,
linux-kernel, Igor Velkov
Hi Shawn,
On 2026/10/26, Shawn Lin wrote:
> The host cannot distinguish this case.
The controller seems to tell before the config read. On 26 Oct the
link came back 2.9-4.5 ms after a hot reset in ~50 cases, all fine,
and 10.9-35.4 ms in 8, each followed by an abort on the next config
read. PCIE_CLIENT_BASIC_STATUS0 read 0x240 after each of 4 slow links
and 0x1240 after each of 16 fast ones. What does bit 12 mean, and can
the driver rely on it after link training?
> You've tried PERST# with the patch 1 applied. So perhaps it's doesn't
> help.
Patch 1 pulses PERST# only after a training timeout. With PERST# in
the DT a slow link still occurred (25 ms, then an abort).
Re-initializing the port, without PERST# or a power cycle, brought
each of 4 slow links back in 2.9 ms with the endpoint answering.
> I've attached a vendor's debug patch, perhaps you could try it without
> your patch.
It hooks do_serror() only and registers after pci_host_probe(). Here
both SErrors and synchronous external aborts occur, at probe and on
resume (the cover had that wrong), so we will move the hook before
pci_host_probe() when we try it.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399
2026-10-26 18:28 ` Igor Velkov
@ 2026-10-27 0:44 ` Shawn Lin
2026-10-27 1:15 ` Igor Velkov
0 siblings, 1 reply; 7+ messages in thread
From: Shawn Lin @ 2026-10-27 0:44 UTC (permalink / raw)
To: Igor Velkov
Cc: shawn.lin, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Rob Herring,
Heiko Stuebner, linux-pci, linux-rockchip, linux-arm-kernel,
linux-kernel
在 2026/10/27 星期二 2:28, Igor Velkov 写道:
> Hi Shawn,
>
> On 2026/10/26, Shawn Lin wrote:
>> The host cannot distinguish this case.
>
> The controller seems to tell before the config read. On 26 Oct the
> link came back 2.9-4.5 ms after a hot reset in ~50 cases, all fine,
> and 10.9-35.4 ms in 8, each followed by an abort on the next config
> read. PCIE_CLIENT_BASIC_STATUS0 read 0x240 after each of 4 slow links
> and 0x1240 after each of 16 fast ones. What does bit 12 mean, and can
> the driver rely on it after link training?
>
I have no idea about it. The PCIE_CLIENT_BASIC_STATUS0 says:
14:12 RO max_payload_size
So you are saying different MPS in different cases, not linking status.
>> You've tried PERST# with the patch 1 applied. So perhaps it's doesn't
>> help.
>
> Patch 1 pulses PERST# only after a training timeout. With PERST# in
> the DT a slow link still occurred (25 ms, then an abort).
> Re-initializing the port, without PERST# or a power cycle, brought
> each of 4 slow links back in 2.9 ms with the endpoint answering.
>
>> I've attached a vendor's debug patch, perhaps you could try it without
>> your patch.
>
> It hooks do_serror() only and registers after pci_host_probe(). Here
> both SErrors and synchronous external aborts occur, at probe and on
> resume (the cover had that wrong), so we will move the hook before
> pci_host_probe() when we try it.
Yep.
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399
2026-10-27 0:44 ` Shawn Lin
@ 2026-10-27 1:15 ` Igor Velkov
0 siblings, 0 replies; 7+ messages in thread
From: Igor Velkov @ 2026-10-27 1:15 UTC (permalink / raw)
To: Shawn Lin
Cc: Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Helgaas, Rob Herring,
Heiko Stuebner, linux-pci, linux-rockchip, linux-arm-kernel,
linux-kernel, Igor Velkov
On 2026/10/27, Shawn Lin wrote:
> I have no idea about it. The PCIE_CLIENT_BASIC_STATUS0 says:
>
> 14:12 RO max_payload_size
>
> So you are saying different MPS in different cases, not linking status.
You're right, thanks. Our two reads came from different points: the
slow-link one before host_init_port() sets the MPS to 256 bytes, the
other after it, so bit 12 says nothing about the link. The link-up
time after the hot reset remains the only signal we have: 2.9-4.5 ms
fine, 10.9-35.4 ms aborts.
^ permalink raw reply [flat|nested] 7+ messages in thread