mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Shawn Lin <shawn.lin@rock-chips.com>
To: iav@iav.lv, "Lorenzo Pieralisi" <lpieralisi@kernel.org>,
	"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
	"Manivannan Sadhasivam" <mani@kernel.org>,
	"Bjorn Helgaas" <bhelgaas@google.com>
Cc: shawn.lin@rock-chips.com, Rob Herring <robh@kernel.org>,
	Heiko Stuebner <heiko@sntech.de>,
	linux-pci@vger.kernel.org, linux-rockchip@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399
Date: Mon, 26 Oct 2026 17:08:01 +0800	[thread overview]
Message-ID: <4316c1da-f7ff-4fa5-a330-512800474e45@rock-chips.com> (raw)
In-Reply-To: <20261024-rockchip-pcie-resume-v1-0-58e54a5cf5f1@iav.lv>

[-- 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


  parent reply	other threads:[~2026-10-26  9:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-24  1:02 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 [this message]
2026-10-26 18:28   ` [PATCH RFC 0/2] PCI: rockchip-host: Retry training and hot-reset a JMB585 on RK3399 Igor Velkov
2026-10-27  0:44     ` Shawn Lin
2026-10-27  1:15       ` Igor Velkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4316c1da-f7ff-4fa5-a330-512800474e45@rock-chips.com \
    --to=shawn.lin@rock-chips.com \
    --cc=bhelgaas@google.com \
    --cc=heiko@sntech.de \
    --cc=iav@iav.lv \
    --cc=kwilczynski@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=lpieralisi@kernel.org \
    --cc=mani@kernel.org \
    --cc=robh@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®