On Wed, Jun 11, 2025 at 12:51:42PM +0200, Niklas Cassel wrote: > Commit ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can > detect Link Up") changed so that we no longer call dw_pcie_wait_for_link(), > and instead enumerate the bus directly after receiving the Link Up IRQ. > > This means that there is no longer any delay between link up and the bus > getting enumerated. Minor quibble about "no longer any delay": dw_pcie_wait_for_link() doesn't contain any explicit delay *after* we notice the link is up, so we didn't guarantee sufficient delay even before ec9fd499b9c6. If the link came up before the first check, dw_pcie_wait_for_link() didn't delay at all. Otherwise, it delayed 90ms * N, and we have no idea when in the 90ms period the link came up, so the post link-up delay was effectively some random amount between 0 and 90ms. I would propose something like: PCI: dw-rockchip: Wait PCIE_T_RRS_READY_MS after link-up IRQ Per PCIe r6.0, sec 6.6.1, software must generally wait a minimum of 100ms (PCIE_T_RRS_READY_MS) after Link training completes before sending a Configuration Request. Prior to ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up"), dw-rockchip used dw_pcie_wait_for_link(), which waited between 0 and 90ms after the link came up before we enumerate the bus, and this was apparently enough for most devices. After ec9fd499b9c6, rockchip_pcie_rc_sys_irq_thread() started enumeration immediately when handling the link-up IRQ, and devices (e.g., Laszlo Fiat's PLEXTOR PX-256M8PeGN NVMe SSD) may not be ready to handle config requests yet. Delay PCIE_T_RRS_READY_MS after the link-up IRQ before starting enumeration. > As per PCIe r6.0, sec 6.6.1, a Downstream Port that supports Link speeds > greater than 5.0 GT/s, software must wait a minimum of 100 ms after Link > training completes before sending a Configuration Request. > > Add this delay in the threaded link up IRQ handler in order to satisfy > the requirements of the PCIe spec. > > Laszlo Fiat reported (off-list) that his PLEXTOR PX-256M8PeGN NVMe SSD is > no longer functional, and simply reverting commit ec9fd499b9c6 ("PCI: > dw-rockchip: Don't wait for link since we can detect Link Up") makes his > SSD functional again. Adding the 100 ms delay as required by the spec also > makes the SSD functional again. > > Cc: Laszlo Fiat <laszlo.fiat@xxxxxxxxx> > Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up") I would argue that 0e898eb8df4e ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver") is the right Fixes: commit here because dw_pcie_wait_for_link() *never* waited the required time, and it's quite possible that other devices don't work correctly. The delay was about 90ms - <time required for link training>, so could be significantly less than 100ms. > Signed-off-by: Niklas Cassel <cassel@xxxxxxxxxx> > --- > drivers/pci/controller/dwc/pcie-dw-rockchip.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c > index 93171a392879..a941a239cbfc 100644 > --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c > +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c > @@ -459,6 +459,13 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg) > if (reg & PCIE_RDLH_LINK_UP_CHGED) { > if (rockchip_pcie_link_up(pci)) { > dev_dbg(dev, "Received Link up event. Starting enumeration!\n"); > + /* > + * As per PCIe r6.0, sec 6.6.1, a Downstream Port that > + * supports Link speeds greater than 5.0 GT/s, software > + * must wait a minimum of 100 ms after Link training > + * completes before sending a Configuration Request. > + */ I think the comment at the PCIE_T_RRS_READY_MS definition should be enough (although it might need to be updated to mention link-up). This delay is going to be a standard piece of every driver, so it won't require special notice. > + msleep(PCIE_T_RRS_READY_MS); > /* Rescan the bus to enumerate endpoint devices */ > pci_lock_rescan_remove(); > pci_rescan_bus(pp->bridge->bus); > -- > 2.49.0 >